The grid operation has several issues :
xstep
or ystep
(resp. stepx
or stepy
in PGF) are set to 0
or negative the division or dimension error is thrown;(1.5,1.5) grid (-2.5, -1.5)
the end coordinate is set to (1, 1.5) which is the end of tha last drawn vertical line. Which is inconsistent with (0,0) rectangle (-2.5, -1.5)
.As I don't see how to make a push request on sourceforge I submit here a purposal for a fix of \pgf@pathgrid
that do the following :
stepx > .01pt
;stepy > .01pt
;\documentclass[tikz,border=7pt]{standalone} \makeatletter \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% \pgf@ya=\pgf@y% % Swap coordinates if one of them is smaller than the other: \ifdim\pgf@xa>\pgf@xb% \pgf@x=\pgf@xb% \pgf@xb=\pgf@xa% \pgf@xa=\pgf@x% \fi% \ifdim\pgf@ya>\pgf@yb% \pgf@y=\pgf@yb% \pgf@yb=\pgf@ya% \pgf@ya=\pgf@y% \fi% \ifdim \pgf@yc > .01pt\relax% if to draw horizontal lines \c@pgf@counta=\pgf@ya\relax% \c@pgf@countb=\pgf@yc\relax% \divide\c@pgf@counta by\c@pgf@countb\relax% \pgfutil@tempdima=\c@pgf@counta\pgf@yc\relax% \ifdim\pgfutil@tempdima<\pgf@ya% \advance\pgfutil@tempdima by\pgf@yc% \fi% \pgfutil@tempdimb\pgf@x \pgfutil@loop% horizontal lines {% \pgf@xa=\pgfutil@tempdimb% \pgf@ya=\pgfutil@tempdima% \pgf@pos@transform{\pgf@xa}{\pgf@ya} \pgf@nlt@moveto{\pgf@xa}{\pgf@ya}% \pgf@xa=\pgf@xb% \pgf@ya=\pgfutil@tempdima% \pgf@pos@transform{\pgf@xa}{\pgf@ya} \pgf@nlt@lineto{\pgf@xa}{\pgf@ya}% }% \advance\pgfutil@tempdima by\pgf@yc% \ifdim\pgfutil@tempdima<\pgf@yb% \pgfutil@repeat% \advance\pgfutil@tempdima by-0.01pt\relax% \ifdim\pgfutil@tempdima<\pgf@yb% {% \pgf@xa=\pgfutil@tempdimb% \pgf@ya=\pgfutil@tempdima% \pgf@pos@transform{\pgf@xa}{\pgf@ya} \pgf@nlt@moveto{\pgf@xa}{\pgf@ya}% \pgf@xa=\pgf@xb% \pgf@ya=\pgfutil@tempdima% \pgf@pos@transform{\pgf@xa}{\pgf@ya} \pgf@nlt@lineto{\pgf@xa}{\pgf@ya}% }% \fi% \fi% \ifdim \pgf@xc > .01pt\relax% if to draw vertical lines \c@pgf@counta=\pgf@x\relax% \c@pgf@countb=\pgf@xc\relax% \divide\c@pgf@counta by\c@pgf@countb\relax% \pgfutil@tempdimb=\c@pgf@counta\pgf@xc\relax% \ifdim\pgfutil@tempdimb<\pgf@xa% \advance\pgfutil@tempdimb by\pgf@xc% \fi% \pgfutil@loop% vertical lines {% \pgf@xc=\pgfutil@tempdimb% \pgf@yc=\pgf@ya% \pgf@pos@transform{\pgf@xc}{\pgf@yc} \pgf@nlt@moveto{\pgf@xc}{\pgf@yc}% \pgf@xc=\pgfutil@tempdimb% \pgf@yc=\pgf@yb% \pgf@pos@transform{\pgf@xc}{\pgf@yc} \pgf@nlt@lineto{\pgf@xc}{\pgf@yc}% }% \advance\pgfutil@tempdimb by\pgf@xc% \ifdim\pgfutil@tempdimb<\pgf@xb% \pgfutil@repeat% \advance\pgfutil@tempdimb by-0.01pt\relax% \ifdim\pgfutil@tempdimb<\pgf@xb% {% \pgf@xc=\pgfutil@tempdimb% \pgf@yc=\pgf@ya% \pgf@pos@transform{\pgf@xc}{\pgf@yc} \pgf@nlt@moveto{\pgf@xc}{\pgf@yc}% \pgf@xc=\pgfutil@tempdimb% \pgf@yc=\pgf@yb% \pgf@pos@transform{\pgf@xc}{\pgf@yc} \pgf@nlt@lineto{\pgf@xc}{\pgf@yc}% }% \fi% \fi% \pgf@process{#3}% \pgf@pos@transform{\pgf@x}{\pgf@y}% \pgf@nlt@moveto{\pgf@x}{\pgf@y}% } \makeatother \begin{document} \begin{tikzpicture} \begin{scope}[rotate=30] \draw[help lines, red] (0,0) node[right]{(0,0)} rectangle (-5,5) node[left]{(-5,5)}; \draw[xstep=21pt, ystep=0mm,ultra thick] (0,0) grid (-5,5) -- ++(30:1); \end{scope} \end{tikzpicture} \end{document}
Note: The arbitrary .01pt
can be replaced by the more logical \pgflinewidth
but what if \pgflinewidth=0
...
Many thanks for reporting and providing the patch, which is now included to the code.
Thanks for considering my merge request. It's nice to now that we can help the project we like.
Last edit: Kpym 2018-05-29
Unfortunately, the fix breaks nonlinear transformations, for example
in this case, the grid lines are not transformed properly.
I will roll back the change for now and reopen the issue until we have time to fix it (as we do not want to break the existing functionality as part of the next release)
Last edit: Christian Feuersänger 2019-01-01
The problem affects examples in the manual, see documentation for the curvilinear library in Section 107.4.7
The commit which introduced the faulty version was 0a65c10132098c5b4f035b3df1e0df393eac218b
my revert is 92735cd0884112dc439854061acd5a427f92eacd
The error comes from bad copy/paste in the code (I think) :(
The faulty line is 1187 with the code
This line should simply be deleted.
The code is supposed to do only three things :
check that the
y
step is positivecheck that the
x
step is positiveand move at the destination position at the end
So I don't know why this line was added there, but it is probably a copy/paste error.
There is a similar line after the first check (that was already in the code) but this second change of
\c@pgf@counta
is not in the original code ... so there is no reason to be in the new code.Sorry for that.
I made a new merge request with the modified line 1187.
Now I partially remember why this line was changed : it is not a copy paste error.
The original code was :
\c@pgf@counta=\pgfutil@tempdimb\relax%
but as\pgfutil@tempdimb
is set to be\pgf@x
in the\ifdim
part for the y step I was thinking that if this code is not executed (in the case \pgf@yc is 0 for example) in place to set\c@pgf@counta
from\pgfutil@tempdimb
it should be set to\pgf@x
... I was wrong.To be honest I do not understand in the case
[ysetp=0]
what is the value of\pgfutil@tempdimb
, but all my tests confirm that it works properly with ou without non linear transform.Excellent, thanks for the analysis and the fast response. The example appears to work and your revised fix is now part of PGF.
Thanks again for contributing!
The "new" line 1187 is not good. I have made another merge requaest.
Let me explain :
\c@pgf@counta=\pgfutil@tempdimb\relax%
and is used in a calculation to check from where to start the loop, because the first line is not necessarilly stratong from the starting point. But in this version at this moment\pgfutil@tempdimb
has the same value as\pgf@xa
, which is more natural to be used here. And when there is no nolinear transform\pgf@xa
is also equa to\pgf@x
.\pgfutil@tempdimb
by\pgf@x
which was backward incompatible in the case of nonlinear transform.\pgfutil@tempdimb
which was backward compatible (in the caseysetp > 0
) but is not good in the caseystep=0
.\pgfutil@tempdimb
by\pgf@xa
which seems to be backward compatible and consistent with the new behaviour whenystep=0
.Sorry for this mess, but to be honnest the original code is not very clean at ths place :(
Thank you for the follow-up. I merged your fixed code.
Thanks. I hope that will be the end of this Ticket :)