我有一个(角度/值)对列表。我想使用 TikZ
- 按照这些角度绘制具有这些值的节点(简单),
- 然后从节点 i 到 i+1 画一条边,以节点 i 的值作为标签(这一点并不容易)。
我目前的想法是:将值存储在 pgfkeys 中,键与节点名称相同。然后,可以轻松访问值。问题是,我无法让 pgfkeyssetvalue 先评估节点名称。
例子:
\documentclass[tikz]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\draw [dotted] (0,0) circle (2cm);
% draw nodes on a circle, remembering their value fails:
\foreach \angle/\value [count = \i] in {0/17, 45/22, 80/5, 140/12} {
\node [circle, draw, fill=white] (p\i) at (\angle:2cm) {\value};
\pgfkeyssetvalue{/nodevalues/p\i}{\value}
}
% to illustrate that it works with explicit node names:
\pgfkeyssetvalue{/nodevalues/p1}{17}
\pgfkeyssetvalue{/nodevalues/p2}{22}
% edges:
\foreach [evaluate = {\j=int(mod(\i, 4)+1)}] \i in {1,...,4}
\draw [->] (p\i) to [bend right=45] node[midway] {\pgfkeysvalueof{/nodevalues/p\i}} (p\j) ;
\end{tikzpicture}
\end{document}
这样可以正确绘制手动设置的键 /nodevalues/p1 和 /nodevalues/p2 的边。但是 pgfkeyssetkeys 并没有达到我想要的效果。预期结果是 5->12 弧的标签为 5,而 12->17 的标签为 12。
答案1
这是我的做法:建立一个列表并重复使用其中的条目。
\documentclass[tikz,border=3.14mm]{standalone}
\begin{document}
\begin{tikzpicture}
\draw [dotted] (0,0) circle (2cm);
% draw nodes on a circle, remembering their value no longer fails:
\foreach \angle/\value [count = \i] in {0/17, 45/22, 80/5, 140/12} {
\node [circle, draw, fill=white] (p\i) at (\angle:2cm) {\value};
\ifnum\i=1
\xdef\Lst{\value}
\else
\xdef\Lst{\Lst,\value}
\fi
}
% edges:
\foreach [evaluate = {\j=int(mod(\i, 4)+1)}] \i in {1,...,4}
\pgfmathsetmacro{\X}{{\Lst}[\i-1]}
\typeout{\X}
\draw [->] (p\i) to [bend right=45] node[midway,auto,swap]
{\X} (p\j) ;
\end{tikzpicture}
\end{document}
编辑:我认为这是个好问题,也值得解释一下为什么它失败了。本质上,循环在本地执行键,而您需要将它们设置为全局。此全球化已由 @percusse 在这个很好的答案一旦运用了它,你原来的方法也能起作用。
\documentclass[tikz,border=3.14mm]{standalone}
\begin{document}
\begin{tikzpicture}
\draw [dotted] (0,0) circle (2cm);
% draw nodes on a circle, remembering their value no longer fails:
\foreach \angle/\value [count = \i] in {0/17, 45/22, 80/5, 140/12} {
\node [circle, draw, fill=white] (p\i) at (\angle:2cm) {\value};
\begingroup\globaldefs=1\relax
\edef\temp{\noexpand\pgfkeyssetvalue{/nodevalues/p\i}{\value}}
\temp
\endgroup
}
% edges:
\foreach [evaluate = {\j=int(mod(\i, 4)+1)}] \i in {1,...,4}
\draw [->] (p\i) to [bend right=45] node[midway] {\pgfkeysvalueof{/nodevalues/p\i}} (p\j) ;
\end{tikzpicture}
\end{document}
另一种可能性是采用Henri Menke 记住节点内容的技巧如果您要求的话,我很乐意解释这一点。
答案2
只是为了好玩,一个\foreach
可以做你想做的事的单一的东西。
\documentclass[tikz,margin=2mm]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\draw [dotted] (0,0) circle (2cm);
\foreach \angle/\value [count = \i, count=\j from 0, remember=\value as \oldvalue] in {0/17, 45/22, 80/5, 140/12} {
\node [circle, draw, fill=white] (p\i) at (\angle:2cm) {\value};
\ifnum\j>0
\draw[->] (p\j) to [bend right=45] node[midway,auto,swap] {\oldvalue} (p\i);
\fi
\ifnum\i=4
\draw[->] (p\i) to [bend right=45] node[midway,auto,swap] {\value} (p1);
\fi
}
\end{tikzpicture}
\end{document}
答案3
pgf keys
无需使用而仅使用本机的操作功能就有可能解决您的问题\foreach
。
在这里,我使用第一个循环来绘制,并使用第二个循环在节点之间nodes
创建操作arrows
edge
\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
\draw [dotted] (0,0) circle (2cm);
% create the node
\foreach \angle/\value [count=\i,remember=\angle as \lastangle (initially 140),remember=\i as \lasti (initially 4)] in {0/17, 45/22, 80/5, 140/12} {
\node (\i) at (\angle:2cm) {\value};
}
% draw arrow with edge operation
\foreach \value [count=\i,remember =\i as \lasti (initially 4),remember=\value as \lvalue (initially 12)] in {17,22,5,12}{
\path[->](\lasti) edge[bend right=45] node[midway,auto,swap]{\lvalue}(\i);
}
\end{tikzpicture}
\end{document}