10

Look at next code, when I want to draw a grid from right to left or top to bottom, vertical or horizontal lines are not drawn, even with xstep=-1 or ystep=-1 (as it's suggested in Jake's answer in Grid missing horizontal lines).

What am I missing? I'm using TikZ's CVS version.

\documentclass[border=2mm]{standalone}
\usepackage{tikz}

\newcommand{\arrow}[2]{\draw[->,blue,thick,shorten <=5mm, shorten >=5mm] #1 -- #2 ;}

\begin{document}

\begin{tikzpicture}
\draw[help lines] (-2,-2) grid (2,2); 
\draw[red,fill] (0,0) circle (1mm) node[below right] {(0,0)};
\node[anchor=south,align=center] at (0,2){(-2,-2) to (2,2)};
\arrow{(-2,-2)}{(2,2)}
\end{tikzpicture}

\begin{tikzpicture}
\draw[help lines] (-2,2) grid[ystep=-1] (2,-2);
\arrow{(-2,2)}{(2,-2)}
\draw[red,fill] (0,0) circle (1mm) node[above right] {(0,0)};
\node[anchor=south,align=center] at (0,2){(-2,2) to (2,-2)};
\end{tikzpicture}

\begin{tikzpicture}
\draw[help lines] (2,-2) grid[xstep=-1] (-2,2);
\arrow{(2,-2)}{(-2,2)}
\draw[red,fill] (0,0) circle (1mm) node[above right] {(0,0)};
\node[anchor=south,align=center] at (0,2){(2,-2) to (-2,2)};
\end{tikzpicture}

\begin{tikzpicture}
\draw[help lines] (2,2) grid[xstep=-1,ystep=-1] (-2,-2);
\arrow{(2,2)}{(-2,-2)}
\draw[red,fill] (0,0) circle (1mm) node[below right] {(0,0)};
\node[anchor=south,align=center] at (0,2){(2,2) to (-2,-2)};
\end{tikzpicture}

\end{document} 

enter image description here

4
  • 1
    I think what is happening here is that when you saying \draw[help lines] (-2,2) grid[ystep=-1] (2,-2) sets the y grid line to start at y=2. The second coordinate specifies the end point, so the grid is to end at y=-2. So taking the starting value of y=2, adding the value of ystep yields y=1, which is already greater then the end value of y=-2, so the y grid is considered done. Similar explanations apply to the other two examples. Oct 29, 2012 at 0:31
  • I guess the ending test should really take into account if the y-step is negative that the test should be reversed to be less than, or not allow a negative y-step. Oct 29, 2012 at 0:34
  • @PeterGrill From your comments I understand this is a 'bug' in TikZ. Isn't it?
    – Ignasi
    Oct 29, 2012 at 8:21
  • If the documentation say that that should have worked then it is probably a bug. Otherwise, it is just not the way things work and grids are drawn from bottom left to top right. Oct 29, 2012 at 17:20

1 Answer 1

8

EDIT : This issue is now fixed in the current development version (CVS) of TikZ/PGF. The fix is not what is proposed below but from Till Tantau's comment:

Fixed in CVS. However, negative increments are (still) not allowed. Instead, the two parameters of the pgfpathgrid command are now considered as two corners of a rectangle rather than as explicitly the lower left and upper right corner. This fixes the problem in the way people expect.


If I'm not mistaken somewhere, I've patched the \pgfpathgrid command found in pgfcorepathconstruct.code.tex file. But please let me know if it fails in any other cases that I might have skipped.

With this you don't need to use negative step sizes since it will increment accordingly.

In a nutshell, I've checked if the start point is larger than the finish point and then multiply a few inequalities with -1 with \c@pgf@counta being the conditional variable.

\documentclass{article}
\usepackage{tikz}
\makeatletter


\def\pgfpathgrid{\pgfutil@ifnextchar[{\pgf@pathgrid}{\pgf@pathgrid[]}}
\def\pgf@pathgrid[#1]#2#3{%
  \pgfset{#1}%
  \pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/stepx}}%
  \pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/stepy}}%
  \pgf@process{#3}%
  \pgf@xb=\pgf@x%
  \pgf@yb=\pgf@y%
  \pgf@process{#2}%
  \pgf@xa=\pgf@x\relax%
  \pgf@ya=\pgf@y\relax%
  {%
    % compute bounding box
    % first corner
    \pgf@x=\pgf@xb%
    \pgf@y=\pgf@yb%
    \pgf@pos@transform{\pgf@x}{\pgf@y}%
    \pgf@protocolsizes{\pgf@x}{\pgf@y}%
    % second corner
    \pgf@x=\pgf@xb%
    \pgf@y=\pgf@ya%
    \pgf@pos@transform{\pgf@x}{\pgf@y}%
    \pgf@protocolsizes{\pgf@x}{\pgf@y}%
    % third corner
    \pgf@x=\pgf@xa%
    \pgf@y=\pgf@yb%
    \pgf@pos@transform{\pgf@x}{\pgf@y}%
    \pgf@protocolsizes{\pgf@x}{\pgf@y}%
    % fourth corner
    \pgf@x=\pgf@xa%
    \pgf@y=\pgf@ya%
    \pgf@pos@transform{\pgf@x}{\pgf@y}%
    \pgf@protocolsizes{\pgf@x}{\pgf@y}%
  }%
  \c@pgf@counta=\pgf@y\relax% Truncate the start y coordinate to integer
  \c@pgf@countb=\pgf@yc\relax% Truncate the step size to integer
  \divide\c@pgf@counta by\c@pgf@countb\relax% Truncate the ratio
  \pgf@y=\c@pgf@counta\pgf@yc\relax% % Find the closest integer-multiple of step size to the start
    \ifdim\pgf@ya>\pgf@yb% If the start point is larger than finish 
        \c@pgf@counta=-1\relax
    \else % If everything is fine
        \c@pgf@counta=1\relax
    \fi
  \ifdim\the\c@pgf@counta\pgf@y<\the\c@pgf@counta\pgf@ya% If for some reason it goes too far
    \advance\pgf@y by\the\c@pgf@counta\pgf@yc% take back one step size
  \fi%
  \loop% horizontal lines
    {%
      \pgf@xa=\pgf@x%
      \pgf@ya=\pgf@y%
      \pgf@pos@transform{\pgf@xa}{\pgf@ya}
      \pgfsyssoftpath@moveto{\the\pgf@xa}{\the\pgf@ya}%
      \pgf@xa=\pgf@xb%
      \pgf@ya=\pgf@y%
      \pgf@pos@transform{\pgf@xa}{\pgf@ya}
      \pgfsyssoftpath@lineto{\the\pgf@xa}{\the\pgf@ya}%
    }%
    \advance\pgf@y by\the\c@pgf@counta\pgf@yc% Increment in the - or + direction
  \ifdim\the\c@pgf@counta\pgf@y<\the\c@pgf@counta\pgf@yb% Also compare with the correct sign.
  \repeat%
  \advance\pgf@y by 0.01\dimexpr0pt-(1pt)*\c@pgf@counta\relax%
  \ifdim\the\c@pgf@counta\pgf@y<\the\c@pgf@counta\pgf@yb
    {%
      \pgf@xa=\pgf@x%
      \pgf@ya=\pgf@y%
      \pgf@pos@transform{\pgf@xa}{\pgf@ya}
      \pgfsyssoftpath@moveto{\the\pgf@xa}{\the\pgf@ya}%
      \pgf@xa=\pgf@xb%
      \pgf@ya=\pgf@y%
      \pgf@pos@transform{\pgf@xa}{\pgf@ya}
      \pgfsyssoftpath@lineto{\the\pgf@xa}{\the\pgf@ya}%
    }%
  \fi%
  \c@pgf@counta=\pgf@x\relax%
  \c@pgf@countb=\pgf@xc\relax%
  \divide\c@pgf@counta by\c@pgf@countb\relax%
  \pgf@x=\c@pgf@counta\pgf@xc\relax%
    \ifdim\pgf@xa>\pgf@xb% If the start point is larger than finish 
      \c@pgf@counta=-1\relax
    \else % If everything is fine
      \c@pgf@counta=1\relax
    \fi
  \ifdim\the\c@pgf@counta\pgf@x<\the\c@pgf@counta\pgf@xa%
    \advance\pgf@x by\the\c@pgf@counta\pgf@xc%
  \fi%
  \loop% vertical lines
    {%
      \pgf@xc=\pgf@x%
      \pgf@yc=\pgf@ya%
      \pgf@pos@transform{\pgf@xc}{\pgf@yc}
      \pgfsyssoftpath@moveto{\the\pgf@xc}{\the\pgf@yc}%
      \pgf@xc=\pgf@x%
      \pgf@yc=\pgf@yb%
      \pgf@pos@transform{\pgf@xc}{\pgf@yc}
      \pgfsyssoftpath@lineto{\the\pgf@xc}{\the\pgf@yc}%
    }%
    \advance\pgf@x by\the\c@pgf@counta\pgf@xc% Increment in the - or + direction
  \ifdim\the\c@pgf@counta\pgf@x<\the\c@pgf@counta\pgf@xb% Also compare with the correct sign.
  \repeat%
  \advance\pgf@x by 0.01\dimexpr0pt-(1pt)*\c@pgf@counta\relax%
  \ifdim\the\c@pgf@counta\pgf@x<\the\c@pgf@counta\pgf@xb%
    {%
      \pgf@xc=\pgf@x%
      \pgf@yc=\pgf@ya%
      \pgf@pos@transform{\pgf@xc}{\pgf@yc}
      \pgfsyssoftpath@moveto{\the\pgf@xc}{\the\pgf@yc}%
      \pgf@xc=\pgf@x%
      \pgf@yc=\pgf@yb%
      \pgf@pos@transform{\pgf@xc}{\pgf@yc}
      \pgfsyssoftpath@lineto{\the\pgf@xc}{\the\pgf@yc}%
    }%
  \fi%
}


\makeatother

\newcommand{\arrow}[2]{\draw[->,blue,thick,shorten <=5mm, shorten >=5mm] #1 -- #2 ;}
\begin{document}
\begin{tikzpicture}
\draw[help lines] (-2,-2) grid (2,2); 
\draw[red,fill] (0,0) circle (1mm) node[below right] {(0,0)};
\node[anchor=south,align=center] at (0,2){(-2,-2) to (2,2)};
\arrow{(-2,-2)}{(2,2)}
\end{tikzpicture}
\begin{tikzpicture}
\draw[help lines] (-2,2) grid[ystep=0.33] (2,-2);
\arrow{(-2,2)}{(2,-2)}
\draw[red,fill] (0,0) circle (1mm) node[above right] {(0,0)};
\node[anchor=south,align=center] at (0,2){(-2,2) to (2,-2)};
\end{tikzpicture}

\begin{tikzpicture}
\draw[help lines] (2,-2) grid[xstep=0.66] (-2,2);
\arrow{(2,-2)}{(-2,2)}
\draw[red,fill] (0,0) circle (1mm) node[above right] {(0,0)};
\node[anchor=south,align=center] at (0,2){(2,-2) to (-2,2)};
\end{tikzpicture}
\begin{tikzpicture}
\draw[help lines] (2,2) grid[xstep=0.5,ystep=0.5] (-2,-2);
\arrow{(2,2)}{(-2,-2)}
\draw[red,fill] (0,0) circle (1mm) node[below right] {(0,0)};
\node[anchor=south,align=center] at (0,2){(2,2) to (-2,-2)};
\end{tikzpicture}

\end{document}

enter image description here

2

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .