奇怪的 \foreach[evaluate] 行为

奇怪的 \foreach[evaluate] 行为

使用 TikZ 时出现奇怪的行为评价句法。

为什么底线比其他三条短?

看到底部对角线比其他三条短吗?这不是理想的行为。上图的代码如下:

\documentclass{memoir}
\usepackage{tikz}
\begin{document}

\[
\begin{tikzpicture}
    \foreach \x in {0,...,4} 
        {\node (X\x) at (0,\x) {$\bullet$};
        }
    \foreach \x in {0,...,4} 
        {\node (Y\x) at (3,\x) {$\bullet$};
        }
% start weirdness
    \draw (X0) -- (Y1);
    \foreach \x [evaluate=\x as \sx using \x+1] in {1,...,3}
    {
        \draw (X\x) -- (Y\sx);
    }
% end weirdness. 
% Comment out the above weirdness and uncomment out the following:
%   \draw (X0) -- (Y0);
%   \foreach \x [evaluate=\x as \sx using \x] in {1,...,3}
%   {
%      \draw (X\x) -- (Y\sx);
%   }
\end{tikzpicture}
\]

\end{document}

如果您注释掉“start weirdness”和“end weirdness”之间的行,然后取消注释最后五行,您就会发现问题神奇地解决了:所有的行看起来都一样。

现在所有线的长度都相同。

再次,在原始代码中——以及本文顶部的相关图片中——期望的行为是较短的线。其他三个是不理想的。你能帮我实现期望的行为吗?

谢谢!

答案1

正如我在评论中所写,你需要包装\x+1int

\foreach \x [evaluate=\x as \sx using {int(\x+1)}] in {1,...,3}
    {
        \draw (X\x) -- (Y\sx);
    }

因为否则你会得到像这样的数字2.0,其中.0被解释为锚点。.0(在这种情况下)与东锚点重合,即角度为 0。您的输出显示连接到相应Y-type 节点的东锚点的线。您可能想知道为什么问题没有发生在第二个循环中。这是因为当你说

 evaluate=\x as \sx using \x

Z 不需要解析表达式,也不会添加.0

\documentclass{memoir}
\usepackage{tikz}
\begin{document}

\[
\begin{tikzpicture}
    \foreach \x in {0,...,4} 
        {\node (X\x) at (0,\x) {$\bullet$};
        }
    \foreach \x in {0,...,4} 
        {\node (Y\x) at (3,\x) {$\bullet$};
        }
% start weirdness
    \draw (X0) -- (Y1);
    \foreach \x [evaluate=\x as \sx using {int(\x+1)}] in {1,...,3}
    {
        \draw (X\x) -- (Y\sx);
    }
\end{tikzpicture}   
\quad\mbox{vs.}\quad
\begin{tikzpicture}
% end weirdness. 
% Comment out the above weirdness and uncomment out the following:
    \foreach \x in {0,...,4} 
        {\node (X\x) at (0,\x) {$\bullet$};
        }
    \foreach \x in {0,...,4} 
        {\node (Y\x) at (3,\x) {$\bullet$};
        }
  \draw (X0) -- (Y0);
  \foreach \x [evaluate=\x as \sx using \x] in {1,...,3}
  {
     \draw (X\x) -- (Y\sx);
  }
\end{tikzpicture}
\]

\end{document}

在此处输入图片描述

顺便说一句,我会避免使用\x循环变量,因为它也被使用,也就是说,如果你使用循环calc,你可能会发现其他“怪异之处” 。如果你想要消除间隙,你可以用 Ti 绘制节点calc\xZ。

\documentclass{memoir}
\usepackage{tikz}
\begin{document}

\[
\begin{tikzpicture}[bullet/.style={circle,fill,inner sep=2pt}]
    \path foreach \Y in {0,...,4} 
        {(0,\Y) node[bullet] (X\Y){}
         (3,\Y) node[bullet] (Y\Y) {}
        };
    \foreach \X [evaluate=\X as \Y using {int(\X+1)}] in {0,...,3}
    {
        \draw (X\X) -- (Y\Y);
    }
\end{tikzpicture}   
\]
\end{document}

在此处输入图片描述

Steven B. Segelets 建议使用\the\numexprevaluate。这工作正常,但你根本不需要。

\documentclass{memoir}
\usepackage{tikz}
\begin{document}

\[
\begin{tikzpicture}[bullet/.style={circle,fill,inner sep=2pt}]
    \path foreach \Y in {0,...,4} 
        {(0,\Y) node[bullet] (X\Y){}
         (3,\Y) node[bullet] (Y\Y) {}
        };
    \foreach \X  in {0,...,3}
    {
        \draw (X\X) -- (Y\the\numexpr\X+1);
    }
\end{tikzpicture}   
\]
\end{document}

答案2

我确信有办法tikz做到这一点,但我得出了\x+1需要评估的结论,因此由于它是不可或缺的,所以我使用了\numexpr

\documentclass{memoir}
\usepackage{tikz}
\begin{document}

\[
\begin{tikzpicture}
    \foreach \x in {0,...,4} 
        {\node (X\x) at (0,\x) {$\bullet$};
        }
    \foreach \x in {0,...,4} 
        {\node (Y\x) at (3,\x) {$\bullet$};
        }
% start weirdness
    \draw (X0) -- (Y1);
    \foreach \x [evaluate=\x as \sx using \the\numexpr\x+1\relax] in {1,...,3}
    {
        \draw (X\x) -- (Y\sx);
    }
% end weirdness. 
% Comment out the above weirdness and uncomment out the following:
%   \draw (X0) -- (Y0);
%   \foreach \x [evaluate=\x as \sx using \x] in {1,...,3}
%   {
%      \draw (X\x) -- (Y\sx);
%   }
\end{tikzpicture}
\]

\end{document}

在此处输入图片描述

相关内容