我想生成一个图,其中节点和边的名称由图中的坐标决定,如下所示:
\foreach \x in {0,1,...,6}
\foreach \y in {1,...,4}
\draw (1.5*\x,2.5*\y) circle (3mm) node (\x and \y);
即按坐标将节点命名为 (2 和 4)。我该怎么做?请注意,稍后我想使用此节点名称在另一个循环中生成连接,例如
\foreach \x in {1,...,5}
\draw[->] (1.5*\x and 4) -- (1.5*(\x+1) and 4);
可以做到这一点,或者做与此相当的事情吗?
答案1
这样命名节点存在很大的问题,因为小数表示形状边框上的角度,如(node.south)
或(node.45)
。所以在我看来,你应该严格使用整数。
\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\foreach \x in {0,1,...,6}{
\foreach \y in {1,...,4}{
\begin{scope}[x=1.5cm,y=2.5cm]
\draw (\x,\y) circle (3mm) node (n\x\y){};
\end{scope}
}
}
\foreach \x[count=\xnext from 2] in {1,...,5}{
\draw[->] (n\x 4) -- (n\xnext 4);
}
\end{tikzpicture}
\end{document}
答案2
是的,你可以,你只需要小心正确命名它们,并确保当你尝试访问它们时使用相同的名称:
笔记:
节点名为
(0and 1)
... 。请注意,和坐标(6and 4)
之间没有空格。如果用替换,则可以看到这一点and
\x
node (\x and \y) {} ;
node (\x and \y) {(\x and \y)};
这不是问题,只是需要注意的一点。但是,正如 Jake 提到的,
(1 and 2)
如果您使用节点,则可以为它们命名(\x\space and \y)
,在这种情况下,当您尝试访问它们时,您还需要包括\space
。由于正常的数学计算通常以小数来执行,我过去常常
\pgfmathtruncatemacro{<csname>}{<expression>}
确保我们只使用整数。foreach
我将访问节点的范围调整为,3
以确保您不会尝试访问诸如 之类的节点(7and 4)
,而原始代码正在尝试这样做。此外,1.5*5
会产生7.5
,因此不确定您想在此处访问哪个节点。
代码:
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\foreach \x in {0,1,...,6}
\foreach \y in {1,...,4}
\draw (1.5*\x,2.5*\y) circle (3mm)
node (\x and \y) {} ;
\foreach \x in {1,...,3}{
\pgfmathtruncatemacro{\XnameA}{1.5*\x}%
\pgfmathtruncatemacro{\XnameB}{1.5*(\x+1)}%
\draw[->] (\XnameA and 4) -- (\XnameB and 4);
}
\end{tikzpicture}
\end{document}
答案3
一种简单的方法是通过图中的坐标来命名节点\x;\y
。使用此语法,您可以使用这样的节点\draw (0;1)
。它就像坐标一样,只有分隔符不同。如果您需要绘制复杂的图形,可以添加这样的前缀a \x;\y
。
现在在您的示例中,有一些不清楚的地方:
\draw (1.5*\x,2.5*\y) circle (3mm) node (\x and \y){};
您使用一个节点和一个圆。有时这很有趣,但这里为什么不只使用一个节点或一个坐标呢?
1)
\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\foreach \x in {0,1,...,6}{
\foreach \y in {1,...,4}{
\path (1.5*\x,2.5*\y) coordinate [draw,circle,minimum size=2mm,inner sep=0pt] (\x;\y);
}
}
\foreach \j in {1,...,4}{\draw[->] (0;\j) -- (1;\j);}
\end{tikzpicture}
\end{document}
2)
\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\foreach \x in {0,1,...,6}{
\foreach \y in {1,...,4}{
\node[circle,minimum width=3mm,draw] (\x;\y) at (1.5*\x,2.5*\y) {} ;
}
}
\foreach \j in {1,...,4}{\draw[->] (0;\j) -- (1;\j);}
\end{tikzpicture}
\end{document}
3)
如果你真的想要圆和节点,为什么不使用圆和坐标来避免{}
代码
\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\foreach \x in {0,1,...,6}{
\foreach \y in {1,...,4}{
\draw (1.5*\x,2.5*\y) circle [radius = .3 cm] coordinate[circle] (\x;\y);
}
}
\foreach \j in {1,...,4}{\draw[->] (0;\j) -- (1;\j);}
\end{tikzpicture}
\end{document}
4) 现在要访问节点,我认为最好避免计算。从逻辑上讲,这对整数(\x;\y)
表示一个节点(这是一个双射)。了解为什么需要使用类似的东西1.5*\x
来设计节点将会很有趣。
5)一个更复杂的例子来查看所有问题
\documentclass{scrartcl}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\foreach \x in {0,...,4}{
\foreach \y in {1,...,3}{
\path (1.5*\x,2.5*\y) coordinate [fill=red,circle,minimum size=3mm] (a \x;\y);
}
}
\begin{scope} [shift={(3.5cm,-5cm)}]
\foreach \x in {0,...,4}{
\foreach \y in {1,...,3}{
\path (72*\x:1.5*\y) coordinate [fill=blue,circle,minimum size=3mm] (b \x;\y);
}
}
\end{scope}
\foreach \i in {0,...,4}{
\draw[->,] (a \i;3) to [bend left] (b \i;3);}
\foreach \i [count=\ii from 1] in {0,...,4}{
\pgfmathtruncatemacro\iii{mod(\ii,5)}
\draw[->,blue] (b \i;3) to [bend left] (b \iii;3);}
\end{tikzpicture}
\end{document}