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.

As in here, the code

\draw[step=0.5cm,color=gray] (-1,-1) grid (1,1);

gives me a nice finite 4x4 grid. But when I choose a different starting point, like

\draw[step=0.5cm,color=gray] (2,2) grid (4,4);

then the left and the bottom border of the grid disappears. What is the problem and how can I fix it so that I have all the borders? I know I can draw a rectangle there, but I assume there is some cleaner solution.

share|improve this question
    
Nice question! I added the word "missing" to your title to make it a bit clearer, is that OK? –  Hendrik Vogt Mar 19 '11 at 15:56
    
@Hendrik Vogt: OK, thanks! –  Dadam Mar 20 '11 at 8:51

2 Answers 2

up vote 13 down vote accepted

In the pgfmanual it says on p. 145 that

due to rounding errors, the "last" lines of a grid may be omitted. In this case, you have to add an epsilon to the corner points

In this case, you will have to subtract an epsilon, i.e. a very small value, from the corner point. Something like

\draw[step=0.5cm,color=gray] (2-0.001,2-0.001) grid (4,4);

will work without any visible artefacts.

share|improve this answer

In the pgfmanual, we can read "Note that due to rounding errors, the “last” lines of a grid may be omitted." More precisely, the first lines may be omitted because for the "last" ones, there is a test in the algorithm to recover these lines in the macro \pgf@pathgrid

\advance\pgf@y by-0.01pt\relax%
\ifdim\pgf@y<\pgf@yb%

For example the next code draws all the lines

\begin{tikzpicture} 
\draw[step=.5cm,color=gray] (2,2) grid (3.9999,3.9999);
  \draw[fill=red](0,0) circle (1pt);  
\end{tikzpicture}

An idea to avoid the problem described by the OP, is to modify the macro and to add a test for the first lines : I used \pgf@xx and \pgf@yy I think that it's not a big problem. The "rounding problem" begins with the next lines

  \pgf@yy=\pgf@ya\relax% added
  \advance\pgf@yy-0.01pt\relax% added 
  \ifdim\pgf@y<\pgf@yy% modified 
    \advance\pgf@y by\pgf@yc%
  \fi%

The complete code is

\documentclass{minimal}
\usepackage{tikz}

\makeatletter
\pgfkeys{
  /pgf/stepx/.initial=1cm,
  /pgf/stepy/.initial=1cm,
  /pgf/step/.code={\pgf@process{#1}\pgfkeysalso{/pgf/stepx/.expanded=\the\pgf@x,/pgf/stepy/.expanded=\the\pgf@y}},
  /pgf/step/.value required
}

\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%
  \c@pgf@countb=\pgf@yc\relax%
  \divide\c@pgf@counta by\c@pgf@countb\relax% rounding problem begins here
  \pgf@y=\c@pgf@counta\pgf@yc\relax% 
  \pgf@yy=\pgf@ya\relax% added
  \advance\pgf@yy-0.01pt\relax% added 
  \ifdim\pgf@y<\pgf@yy% modified the problem appears here !!
    \advance\pgf@y by\pgf@yc%
  \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\pgf@yc%
  \ifdim\pgf@y<\pgf@yb%
  \repeat%
  \advance\pgf@y by-0.01pt\relax%
  \ifdim\pgf@y<\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%
  \pgf@xx=\pgf@xa\relax% added 
  \advance\pgf@xx-0.01pt\relax% added 
  \ifdim\pgf@x<\pgf@xx% modified, 
    \advance\pgf@x by\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\pgf@xc%
  \ifdim\pgf@x<\pgf@xb%
  \repeat%
  \advance\pgf@x by-0.01pt\relax%
  \ifdim\pgf@x<\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
\begin{document}


\begin{tikzpicture} 
\draw[step=.5cm,color=gray] (2,2) grid (4,4);
\draw[fill=red](4,4) circle (1pt); 
\end{tikzpicture}    


\begin{tikzpicture}

\draw[step=0.3cm,color=gray] (0,0) grid (1,1);
    \draw[red](0,0)--(1,1);        
  \draw[fill=red](0,0) circle (1pt);  
\end{tikzpicture} 
\begin{tikzpicture}
\draw[step=0.3cm,color=gray] (1,1) grid (2,2);
  \draw[red](1,1)--(2,2); 
    \draw[fill=red](1,1) circle (1pt);        
\end{tikzpicture}     
\end{document}

Now the pgfmanual before discribes the rounding problem, gives : "It is important to note that the grid is always “phased” such that it contains the point (0, 0) if that point happens to be inside the rectangle. Thus, the grid does not always have an intersection at the corner points; this occurs only if the corner points are multiples of the stepping."

So if we examine the code, we can see that if you want the first lines of the grid at the intersection of the corner point (left down), the possibility is to draw a grid from the (0,0) corner and then to move the grid

\begin{tikzpicture} 
  \draw[step=0.5cm,shift={(2,2)}] (0,0) grid (2,2);
\end{tikzpicture}

You can compare

\begin{tikzpicture} 
  \draw[step=0.3cm,shift={(1,1)}] (0,0) grid (1,1);
\end{tikzpicture}

with

\begin{tikzpicture} 
  \draw[step=0.3cm] (1,1) grid (2,2);
\end{tikzpicture}
share|improve this answer
    
@Altermundus: I follow the advice from the author. Although I think he should deal with the rounding errors, not the user. –  Dadam Mar 20 '11 at 9:03
    
@Dadam : You are right and you can choice what you want. I only give an idea about your problem and I think it's possible to find a better algorithm. –  Alain Matthes Mar 20 '11 at 10:39
    
@Altermundus: And I like that idea. It made me look closer at the grids, realizing that they are little bit more tricky ([step=0.3cm](0, 0) grid (1, 1) doesn't give the same result as [step=0.3] (1, 1) grid (2, 2)) and for drawing C arrays, I should consider using table instead of grid. –  Dadam Mar 20 '11 at 11:32
    
@Dadam You need to write \tikz\draw[step=0.3333cm] (0, 0) grid (1, 1); 0.3333in the two codes, If you want the same result (except for the last lines). This is why I write : " because in some cases, it's not possible to add an epsilon!" . In my packages, I define a macro \grid and I made calculus with fp. I know that the code is slower and I don't respect TikZ syntax but ...it's necessary to find a solution –  Alain Matthes Mar 20 '11 at 11:52
    
@Altermundus: But I want [step=0.3cm], not [step=0.3333cm](I would recommend [step=1.0/3]). What I mentioned above is not a bug, it's a feature: according to the pgfmanual, the grid always starts at (0, 0) and is clipped to the rectangle - theoretically. In practice, the boundaries of lines are calculated - and that is the spot where rounding errors occure, I think. –  Dadam Mar 20 '11 at 12:48

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.