如何计算 pgfkeyssetvalue 命令的 *key*?

如何计算 pgfkeyssetvalue 命令的 *key*?

我有一个(角度/值)对列表。我想使用 TikZ

  1. 按照这些角度绘制具有这些值的节点(简单),
  2. 然后从节点 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创建操作arrowsedge

\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}

肿块

相关内容