我如何在 tikz 中使用 for 循环简单地绘制循环图?我目前有这个,但由于加法没有按预期工作,它不起作用,而是被注册为节点“0+1”(而不是简单的节点“1”)。
\begin{tikzpicture}
%counterclockwise order starting top right
\node[draw=none,minimum size=3.15cm,regular polygon,regular polygon sides=6] (a) {};
\node (0) [inner sep=2pt, circle, fill, draw=black] at (a.corner 1) {};
\node (1) [inner sep=2pt, circle, fill, draw=black] at (a.corner 2) {};
\node (2) [inner sep=2pt, circle, fill, draw=black] at (a.corner 3) {};
\node (3) [inner sep=2pt, circle, fill, draw=black] at (a.corner 4) {};
\node (4) [inner sep=2pt, circle, fill, draw=black] at (a.corner 5) {};
\node (5) [inner sep=2pt, circle, fill, draw=black] at (a.corner 6) {};
\foreach \x in {0,1,...,5} {
\draw (\x) to (\x+1);
}
\end{tikzpicture}
另外,当我在这里时,有没有办法避免复制/粘贴 6 次节点创建行?也许 tikz 中有一行代码可以直接创建给定长度的循环,但我也想问一下,以防我想创建更复杂的东西,而一行代码可能不存在。
编辑:我正在尝试立即完成以下工作(也使用 mod),但我得到了一个Arithmetic overflow
,如何解决?
\begin{tikzpicture}
%counterclockwise order starting top right
\node[draw=none,minimum size=3.15cm,regular polygon,regular polygon sides=6] (a) {};
\node (0) [inner sep=2pt, circle, fill, draw=black] at (a.corner 1) {};
\node (1) [inner sep=2pt, circle, fill, draw=black] at (a.corner 2) {};
\node (2) [inner sep=2pt, circle, fill, draw=black] at (a.corner 3) {};
\node (3) [inner sep=2pt, circle, fill, draw=black] at (a.corner 4) {};
\node (4) [inner sep=2pt, circle, fill, draw=black] at (a.corner 5) {};
\node (5) [inner sep=2pt, circle, fill, draw=black] at (a.corner 6) {};
\foreach \x in {0,...,5} {
\def\y{Mod(\x+1,6)}
\draw (\x) to (\y);
}
\end{tikzpicture}
答案1
TikZ 不会像评估坐标那样评估节点名称。您必须事先计算它,而且由于您正在使用,因此\foreach
您可以直接使用键进行计算evaluate
。
\foreach \x[evaluate={\nextX=int(mod(\x+1,6);}] in {0,1,...,5}
\draw (\x) to (\nextX);
\pgfmathsetmacro\nextX{int(mod(\x+1,6))}
这与之前的写作没有太大区别\draw
。
您也可以使用.evaluated
处理程序以及显式版本的节点坐标系
\foreach \x in {0,1,...,5}
\draw (\x) to (node cs: name/.evaluated={int(mod(\x+1,6))});
处理程序.evaluated
评估给定的值并将\pgfmathparse
其结果转发给键。当然,这有点麻烦。
正如 Skillmon 在评论中指出的那样,在这个相当简单的例子中,我们还可以使用 eTeX 和原语\ifnum
来计算下一个节点的数量:
\draw (\x) to (\ifnum\x=5 0\else\the\numexpr\x+1\relax\fi);
空格和的\relax
用处是明确地限定表达式。
当然,如果你经常需要的话,你可以定义一个宏,比如说
\newcommand*{\nextOutOf}[2]{% next #1 out of #2
\ifnum#1=#2 0\else\the\numexpr#1+1\relax\fi}
并将其用作
\draw (\x) to (\nextOutOf{\x}{5});
这将是 的 sans-PGFmath 版本int(mod(\x,5))
。(由于它根本不使用 PGFmath,因此速度也会更快。)
也就是说,有几十种方法可以将点放置在中心周围并将它们连接起来。
您只需将点放置在具有极坐标的循环中即可:
\foreach \x in {0,...,5}
\node (\x) [inner sep=2pt, circle, fill, draw=black] at (\x*60+60:1.5cm) {};
您可以使用chains
您可以
\tikzset{start chain=circle placed {at=(\tikzchaincount*60:1.5cm)}}
\foreach \x in {0,...,5}
\node (\x) [on chain=circle, inner sep=2pt, circle, fill, draw=black] {};
也可以通过使用各种join
该chains
库提供的各种选项自动连接点。
不过,也许graphs
/graphs.standard
库可以为您替换所有工作:
\graph[
nodes={fill, draw, circle, inner sep=2pt},
radius=1.5cm, typeset=, counterclockwise, phase=60
] {
subgraph C_n[n=6]
};
在 TikZpicture 中,regular polygon
我还用一个循环替换了多边形角上的点的位置,该循环同样需要评估锚点的数量。使用与数字连接的node cs:
有点复杂,这就是为什么我使用了低级 eTeX 版本anchor/.evaluated
corner
\the\numexpr\x+1\relax
评估\x + 1
会对 TikZ 解析器进行评估并将结果干净地保留下来。
(这只是因为您的节点从 开始0
,角从1
而需要的。)
你不能在这里使用复杂的数学(事实上,只有整数才有效,基本算术+
,,-
以及*
和/
(
)
有效)。
代码
\documentclass[tikz]{standalone}
\usetikzlibrary{graphs.standard}% for \graph and subgraph C_n
\usetikzlibrary{shapes.geometric}% for regular polygon
\begin{document}
\begin{tikzpicture}
\node[draw=none,minimum size=3cm,regular polygon,regular polygon sides=6] (a) {};
\foreach \x in {0,...,5}
\node (\x) [inner sep=2pt, circle, fill, draw=black] at (a.corner \the\numexpr\x+1\relax) {};
\foreach \x[
evaluate={\nextX=int(mod(\x+1,6);}
] in {0,1,...,5}
\draw (\x) to (\nextX);
\end{tikzpicture}
\begin{tikzpicture}
\foreach \x in {0,...,5}
\node (\x) [inner sep=2pt, circle, fill, draw=black] at (\x*60+60:1.5cm) {};
\foreach \x in {0,1,...,5}
\draw (\x) to (node cs: name/.evaluated={int(mod(\x+1,6))});
\end{tikzpicture}
\begin{tikzpicture}
\graph[
nodes={fill, draw, circle, inner sep=2pt},
radius=1.5cm, typeset=, counterclockwise, phase=60
] {
subgraph C_n[n=6]
};
% nodes are named 1, …, 6
% \draw (2) -- (4);
\end{tikzpicture}
\end{document}