就像这里, 代码
\draw[step=0.5cm,color=gray] (-1,-1) grid (1,1);
给我一个漂亮的 4x4 有限网格。但是当我选择不同的起点时,比如
\draw[step=0.5cm,color=gray] (2,2) grid (4,4);
然后网格的左边框和下边框就消失了。问题是什么?我该如何修复它才能保留所有边框?我知道我可以在那里画一个矩形,但我认为有一些更简洁的解决方案。
答案1
在里面手册第 145 页说
由于舍入误差,网格的“最后”几行可能会被省略。在这种情况下,您必须在角点上添加一个 epsilon
在这种情况下,你必须从角点减去一个 epsilon,即一个非常小的值。例如
\draw[step=0.5cm,color=gray] (2-0.001,2-0.001) grid (4,4);
无需任何可见的伪影即可工作。
答案2
在 pgfmanual 中,我们可以看到“请注意,由于舍入误差,网格的“最后”行可能会被省略。”更准确地说,可以省略第一行,因为对于“最后”行,算法中有一个测试可以在宏中恢复这些行\pgf@pathgrid
\advance\pgf@y by-0.01pt\relax%
\ifdim\pgf@y<\pgf@yb%
例如,下面的代码绘制所有线条
\begin{tikzpicture}
\draw[step=.5cm,color=gray] (2,2) grid (3.9999,3.9999);
\draw[fill=red](0,0) circle (1pt);
\end{tikzpicture}
避免 OP 所述问题的一个想法是修改宏并为前几行添加测试:我曾经\pgf@xx and \pgf@yy
认为这不是一个大问题。“舍入问题”从下几行开始
\pgf@yy=\pgf@ya\relax% added
\advance\[email protected]\relax% added
\ifdim\pgf@y<\pgf@yy% modified
\advance\pgf@y by\pgf@yc%
\fi%
完整代码如下
\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\[email protected]\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\[email protected]\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}
现在,之前的 pgfmanual 描述了rounding problem
,给出了:“重要的是要注意,网格总是“分阶段”的,这样如果该点恰好位于矩形内,它就会包含点 (0, 0)。因此,网格并不总是在角点处有交点;只有当角点是步进的倍数时,才会发生这种情况。”
因此,如果我们检查代码,我们可以看到,如果你想要网格的第一条线位于角点(左下)的交点处,那么可以从(0,0)角绘制一个网格,然后移动网格
\begin{tikzpicture}
\draw[step=0.5cm,shift={(2,2)}] (0,0) grid (2,2);
\end{tikzpicture}
您可以比较
\begin{tikzpicture}
\draw[step=0.3cm,shift={(1,1)}] (0,0) grid (1,1);
\end{tikzpicture}
和
\begin{tikzpicture}
\draw[step=0.3cm] (1,1) grid (2,2);
\end{tikzpicture}