使用 \foreach 时 TikZ 边缘锚点的意外行为

使用 \foreach 时 TikZ 边缘锚点的意外行为

我想使用 \foreach 自动用 TikZ 绘制一个简单的图片;我写了下面的代码(输出如下):

\documentclass[tikz, border=1mm]{standalone}
\begin{document}
\begin{tikzpicture}
  \tikzstyle{every node}=[circle, inner sep=2pt, draw]
  \foreach \i in {0,1,2}{
    \pgfmathsetmacro{\a}{30 + 120*\i}
    \pgfmathsetmacro{\b}{\a + 60}
    \pgfmathsetmacro{\k}{int(\i+3)}
    \node (c\i) at (\a:2) {};
    \node (s\i) at (\b:2) {};
    \node (s\k) at (\b:1) {};
    \draw[dotted] (c\i) -- (s\i);
    \draw (c\i) -- (s\k);
  }
  \foreach \i[count=\ii] in {0,1,2}{
    \pgfmathsetmacro{\j}{mod(\ii, 3)}
    \pgfmathsetmacro{\k}{\i + 3}
    \draw[dotted] (c\j) -- (s\k);
    \draw (c\j) -- (s\i);
  }
\end{tikzpicture}
\end{document}

首次尝试使用 foreach

我预计图片会和下面的图片一样(包括代码):

\documentclass[tikz, border=1mm]{standalone}
\begin{document}
\begin{tikzpicture}
  \tikzstyle{every node}=[circle, inner sep=2pt, draw=black]
  \node (c0) at (30:2) {};
  \node (s0) at (90:2) {};
  \node (s3) at (90:1) {};
  \node (c1) at (150:2) {};
  \node (s1) at (210:2) {};
  \node (s4) at (210:1) {};
  \node (c2) at (270:2) {};
  \node (s2) at (330:2) {};
  \node (s5) at (330:1) {};
  \draw[dotted]
  (s0) -- (c0) -- (s5)
  (s1) -- (c1) -- (s3)
  (s2) -- (c2) -- (s4)
  ;
  \draw
  (s0) -- (c1) -- (s4)
  (s1) -- (c2) -- (s5)
  (s2) -- (c0) -- (s3)
  ;
\end{tikzpicture}
\end{document}

预期输出

问题:为什么这两种情况下的输出不同?具体来说,为什么这两个例子中的边锚定方式不同?

附言:我还可以使用三个循环来自动执行此过程并获得预期结果,以(1)放置坐标,(2)绘制边,以及(3)将节点放置在坐标上 - 这个问题是关于解释上述行为。

答案1

出现差异的原因在于您使用了\pgfmathsetmacro,并得到了 这样的数字1.0,其中.0被解释为east节点的锚点。一种微创修复方法是使用\pgfmathtruncatemacro

\pgfmathtruncatemacro{\j}{mod(\ii, 3)}
\pgfmathtruncatemacro{\k}{\i + 3}

反而。

\documentclass[tikz, border=1mm]{standalone}
\begin{document}
\begin{tikzpicture}
  \tikzstyle{every node}=[circle, inner sep=2pt, draw]
  \foreach \i in {0,1,2}{
    \pgfmathsetmacro{\a}{30 + 120*\i}
    \pgfmathsetmacro{\b}{\a + 60}
    \pgfmathsetmacro{\k}{int(\i+3)}
    \node (c\i) at (\a:2) {};
    \node (s\i) at (\b:2) {};
    \node (s\k) at (\b:1) {};
    \draw[dotted] (c\i) -- (s\i);
    \draw (c\i) -- (s\k);
  }
  \foreach \i[count=\ii] in {0,1,2}{
    \pgfmathtruncatemacro{\j}{mod(\ii, 3)}
    \pgfmathtruncatemacro{\k}{\i + 3}
    \draw[dotted] (c\j) -- (s\k);
    \draw (c\j) -- (s\i);
  }
\end{tikzpicture}
\end{document}

在此处输入图片描述

有很多方法可以重写这个,例如

\documentclass[tikz, border=1mm]{standalone}
\begin{document}
\begin{tikzpicture}
  \tikzstyle{every node}=[circle, inner sep=2pt, draw]
  \foreach \i  [evaluate=\i as \a using {30 + 120*\i}] in {0,1,2}{
    \node (c\i) at (\a:2) {};
    \node (s\i) at (\a+60:2) {};
    \node (s\the\numexpr\i+3) at (\a+60:1) {};
    \draw[dotted] (c\i) -- (s\i);
    \draw (c\i) -- (s\the\numexpr\i+3);
  }
  \foreach \i [count=\ii,
    evaluate=\ii as \j using {int(mod(\ii,3))}] in {0,1,2}{
    \draw[dotted] (c\j) -- (s\the\numexpr\i+3);
    \draw (c\j) -- (s\i);
  }
\end{tikzpicture}
\end{document}

相关内容