我使用 TikZ 的\foreach
迭代器创建一系列节点,然后在它们之间绘制边。首先,我迭代创建节点;然后我迭代节点以将它们相互链接。但是,即使我使用几乎相同的迭代器来创建和链接节点,第一个迭代器刚刚创建的节点对于第二个迭代器而言也是“未知的”。
这些迭代器是在使用 创建的宏中定义的\newcommand
,并且涉及对节点使用样式,这可能是问题的根源。我使用
\foreach \s [count=\i from 1][evaluate=\i as \n using \i+#7] in #2 {
\node[#4={\n}{\s}{black}] at(..,..){};}
其中,#2
是标签列表,#4
是要使用的样式,是#7
开始对节点进行编号的值,然后尝试将节点与
\foreach \i [remember=\i as \j (initially #1)]
[evaluate=\i as \n using \i+#7]
[evaluate=\j as \m using \j+#7] in {1,...,#1} {
\draw[->,red](\n)--(\m);
其中#1
是要创建的节点数( 的长度#2
)。但是,虽然第二个循环中\n
和假设\m
的一组值应该(据我所知)并且看起来(如果我只是将它们打印出来)相同,但我收到了一条错误消息:
程序包 pgf 错误:没有已知的名为 9 的形状
其中 '9' 被替换为任何其他1+#7
数字。
我是否错过了参数求值方式的一些微妙之处?是否发生了一些“转换”,使得看似相同的名称变得不同?例如,我注意到,虽然我得到了“9.0”等,但当我打印出 的值时\n
,错误消息显示“9”(没有小数点)。
请原谅这个 MWE 的复杂性,它需要与需要这种结构的其他一些代码共存,并且我想确保保留在任何解决方案中需要保留的特性。
\documentclass[]{scrartcl}
\usepackage{tikz}
\tikzset{
actions/.style n args={3}{circle,draw=#3,inner sep=0pt,minimum size=7mm,label=center:$#2$,name=#1}
}
\begin{document}
\newcommand{\graphring}[7]{
% Arguments
% 1 = Number of nodes
% 2 = List of labels for nodes (unused in example)
% 3 = Sense of sequence of nodes (1 or -1)
% 4 = Node style
% 5 = Drawing scale factor
% 6 = Angular position for first node
% 7 = Number of previous nodes; added to each node number
\foreach \s [count=\i from 1] % \i = Index for positioning; \s = State for labeling
[evaluate=\i as \angle using #6+(#3)*(\i-1)*(360/#1)]
[evaluate=\i as \n using \i+#7] in #2 { % \n = Number/name for identification
\node[#4={\n}{\s}{black}] at({#5*cos(\angle))},{#5*sin(\angle))}){};
}
\foreach \i [remember=\i as \j (initially #1)]
[evaluate=\i as \n using \i+#7]
[evaluate=\j as \m using \j+#7] in {1,...,#1} {
\draw[->,red](\n)--(\m); % ERROR: Package pgf Error: No shape named <1+#7> is known
}
}
\begin{center}
\begin{tikzpicture}[scale=3.0]
\graphring{8}{{e,r,r^2,r^3,r^4,r^5,r^6,r^7}}{-1}{actions}{1.0}{90}{0};
\graphring{8}{{f,fr,fr^2,fr^3,fr^4,fr^5,fr^6,fr^7}}{1}{actions}{2.0}{90}{8};
\end{tikzpicture}
\end{center}
\end{document}
答案1
第一个循环将节点命名为1.0
、2.0
等等。您需要使用evaluate=\i as \n using int(\i+#7)
(以及其他循环的等效方法)来截断小数部分:
\documentclass[]{article}
\usepackage{tikz}
\tikzset{
actions/.style n args={3}{circle,draw=#3,inner sep=0pt,minimum size=7mm,label=center:$#2$,name=#1}
}
\begin{document}
\newcommand{\graphring}[7]{
% Arguments
% 1 = Number of nodes
% 2 = List of labels for nodes (unused in example)
% 3 = Sense of sequence of nodes (1 or -1)
% 4 = Node style
% 5 = Drawing scale factor
% 6 = Angular position for first node
% 7 = Number of previous nodes; added to each node number
\foreach \s [count=\i from 1] % \i = Index for positioning; \s = State for labeling
[evaluate=\i as \angle using #6+(#3)*(\i-1)*(360/#1)]
[evaluate=\i as \n using int(\i+#7)] in #2 { % \n = Number/name for identification
\node[#4={\n}{\s}{black}] at({#5*cos(\angle))},{#5*sin(\angle))}){};
}
\foreach \i [remember=\i as \j (initially #1)]
[evaluate=\i as \n using int(\i+#7)]
[evaluate=\j as \m using int(\j+#7)] in {1,...,#1} {
\draw[->,red](\n)--(\m);
}
}
\begin{center}
\begin{tikzpicture}[scale=3.0]
\graphring{8}{{e,r,r^2,r^3,r^4,r^5,r^6,r^7}}{-1}{actions}{1.0}{90}{0};
\graphring{8}{{f,fr,fr^2,fr^3,fr^4,fr^5,fr^6,fr^7}}{1}{actions}{2.0}{90}{8};
\end{tikzpicture}
\end{center}
\end{document}
答案2
您使用\n
和\m
作为节点名称,但您定义的节点没有命名。这里的“形状”表示“节点”。请注意,节点名称的格式是<name>.<anchor>
部分.<anchor>
可选的。如果您使用普通数学运算的结果作为节点名称,则整数部分将用作名称,小数部分将作为锚点。数字锚点将作为度数。
要解决此问题,您需要在创建和连接节点时使用正确的节点名称。您使用name
来命名节点,其中的小数部分可能会被视为实际节点名称,这之后会失败,因为您以后无法引用这样的名称。