我尝试使用嵌套\foreach
循环在许多节点之间创建边。
\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\node (a) at (0, 1) {};
\node (b) at (0, -1) {};
\node (c) at (1, 0) {};
\node (d) at (-1, 0) {};
\foreach \from/\targets in {%
b/d,%
{a/b,c,d}%
} {
\typeout{\from-\targets}
\foreach \to in {\targets} {
\typeout{ \from-\to}
\path (\from) edge (\to);
}
}
\end{tikzpicture}
\end{document}
但这失败了,出现了神秘的错误
b-d
b-d
a-b,c,d
a-b,c,d
! Package PGF Math Error: Unknown function `b' (in 'b').
如\typeout
错误显示之前所示,似乎\targets
没有展开,因此解释为单个参数而不是列表。此时可以强制展开吗?或者还有其他方法可以修复它吗?
答案1
您需要从内部循环中删除括号。也就是说,您不应该将 传递{\targets}
给\foreach
循环,而应该传递\targets
。
\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\node (a) at (0, 1) {};
\node (b) at (0, -1) {};
\node (c) at (1, 0) {};
\node (d) at (-1, 0) {};
\foreach \from/\targets in {%
b/d,%
{a/b,c,d}%
} {
\typeout{\from-\targets}
\foreach \to in \targets {
\typeout{ \from-\to}
\path (\from) edge (\to);
}
}
\end{tikzpicture}
\end{document}
答案2
除了问题\foreach
之外,我认为语法
\path (b) edge (d)
(a) edge (b) edge (c) edge (d);
变得更加自然。在边到边的基础上更改边缘选项也更加容易(或者也可以更改多个边缘):
\path (b) edge (d) {[thick]
(a) edge (b) edge[green] (c) edge[red,->] (d)};
不过,类似的事情仍然可以做\foreach
,比如说
\path (b) edge (d) {[thick]
(a) \foreach \opt/\p in {/b, green/c, {red,->}/d}
{edge[style/.expand once=\opt] (\p)}};
和我的qrr.misc库(代码类似于我的另一个答案)可以做到
\path (b) edge (d) {[thick]
(a) [edges to={b,[green] c, [{red,->}] d}]};
应该注意的是,,
选项中的 必须以某种方式受到保护,要么采用所示方式,要么通过{[red, ->] d}
,即将整个内容括在括号中。(这可以使其更强大,或者可以更改为使用(
和)
来围绕坐标,而不是使用,
,但实现将需要更多解析。)
代码
\documentclass[tikz]{standalone}
\usetikzlibrary{qrr.misc}
\begin{document}
\begin{tikzpicture}
\node (a) at (0, 1) {}; \node (b) at (0, -1) {};
\node (c) at (1, 0) {}; \node (d) at (-1, 0) {};
\path (b) edge (d) {[thick]
(a) edge (b) edge[green] (c) edge[red,->] (d)};
\end{tikzpicture}
\begin{tikzpicture}
\node (a) at (0, 1) {}; \node (b) at (0, -1) {};
\node (c) at (1, 0) {}; \node (d) at (-1, 0) {};
\path (b) edge (d) {[thick]
(a) \foreach \opt/\p in {/b, green/c, {red,->}/d}
{edge[style/.expand once=\opt] (\p)}};
\end{tikzpicture}
\begin{tikzpicture}
\node (a) at (0, 1) {}; \node (b) at (0, -1) {};
\node (c) at (1, 0) {}; \node (d) at (-1, 0) {};
\path (b) edge (d) {[thick]
(a) [edges to={b,[green] c, [{red,->}] d}]};
\end{tikzpicture}
\end{document}
输出
答案3
重要的是在指定要处理的列表中的元素的方式要保持一致\foreach
。
在下面的方法中,我发现这种方法更直观,在外循环的第一次迭代中\targets
扩展到,在第二次迭代中扩展到。因此,为内循环指定的方法可以按预期工作。{b}
{b,c,d}
\foreach \to in \targets
\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\node (a) at (0, 1) {};
\node (b) at (0, -1) {};
\node (c) at (1, 0) {};
\node (d) at (-1, 0) {};
\foreach \from/\targets in {b/{d},a/{b,c,d}}
{%
\typeout{\from-\targets}
\foreach \to in \targets
{%
\typeout{ \from-\to}
\path (\from) edge (\to);
}
}
\end{tikzpicture}
\end{document}