缺少 TikZ 网格边框

缺少 TikZ 网格边框

就像这里, 代码

\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}

相关内容