Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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

share|improve this question
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. –  Peter Grill Oct 29 '12 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. –  Peter Grill Oct 29 '12 at 0:34
    
@PeterGrill From your comments I understand this is a 'bug' in TikZ. Isn't it? –  Ignasi Oct 29 '12 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. –  Peter Grill Oct 29 '12 at 17:20

1 Answer 1

up vote 8 down vote accepted

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

share|improve this answer
    
Thank you very much for your effort. First tests worked but if I find any problem I'll let you know. I think you should consider to submit the patch to TikZ maintainers. –  Ignasi Nov 7 '12 at 9:42
    
@Ignasi Done :) sourceforge.net/tracker/… –  percusse Nov 7 '12 at 10:51

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.