出于严重的技术原因,是否应该避免在一个 tikzpicture 中重新定义节点名称?

出于严重的技术原因,是否应该避免在一个 tikzpicture 中重新定义节点名称?

这是在询问以下方面的意见和经验

  • 是否应该避免(出于我想不出的严重原因)在同一个 tikzpicture 中多次重新定义节点名称。

小例子

\begin{tikzpicture}
  \node (a) at (0,0) []{};


        (..... code, possibly using the name (a)...... )

  \node (a) at (0,1) []{};


        (..... code, possibly using the name (a)...... )         

\end{tikzpicture}

我已经在一些 tikzpictures 中使用它有一段时间了,从来没有发现过问题(这显然可以归因于此)。

首先这样做的原因是——在不需要有意义的名称的应用程序中——不必考虑如何命名节点。(如果该问题还有其他解决方案,我很有兴趣阅读它,但我无法想象;毕竟,命名节点的文本必须输入到 tex 文件中)

如果结果正是人们想要说明的,而且由于“名称空间”似乎严格是“本地的”并且局限于范围内\begin{tikzpicture} ... \end{tikzpicture},所以我找不到这种编程实践有什么严重错误。

尽管如此,我很好奇,这其中是否存在我没​​有想到的危险。我知道,不用说,缺席危险永远无法得到保证。

答案1

这其实没什么大不了的。想象一下,你想并排绘制 10 个不规则矩形,这可能是你能拥有的最短的代码

\documentclass[border=9,tikz]{standalone}
\begin{document}
    \tikz\path node(X){}foreach\i in{0,...,9}{
        (X.east)node(X)[right,minimum size=rnd*30,draw]{}};
\end{document}

你看:关键字X在代码中起着至关重要的作用,尽管它并不代表任何特定的图形对象。事实上,它总是代表最新节点。从此以后,您不必再为诸如其中代表加一的数学结果之\node(\i+1)at(\i.east){}类的问题而苦恼。(您能在不查阅手册或谷歌的情况下执行此计算吗?)(如果您认为可以,那么以下代码中的问题是什么?没有手册/谷歌/编译器)\i+1\i

\tikz\path node(0){}foreach\i[evaluate={\j=\i+1;}]in{0,...,9}{
    (\i.east)node(\j)[right,minimum size=rnd*30,draw]{}};

也许我的编码风格不符合主流。但是……请参阅手册

预定义节点 current bounding box
该节点形状为rectangle。与普通节点不同,其尺寸不断变化,始终反映当前图片边界框的尺寸。
预定义节点 current path bounding box
该节点的形状也是rectangle。其大小是当前路径边界框的大小。
预定义节点 current subpath start
此节点的形状为coordinate,位于当前子路径的开头。这是最后一次移动到操作的位置。

虽然严格来说它们不是真正的节点(作者作弊了,所以它们看起来就像真实的节点一样,但你明白我的意思了。

答案2

下面的代码会跟踪一张图片中所有已定义的名称,如果尝试重新定义名称,则会引发错误。我真的认为使用此代码是个坏主意,而且你之前也问过关于在 TikZ 中做类似事情的奇怪问题。我只能重复之前答案中给出的建议

[...] 从长远来看,这并不像你想象的那么有成效。

还请注意,此解决方案与我的这个答案回答你的另一个奇怪的问题!

\documentclass{article}
\usepackage{xparse}
\usepackage{tikz}

\ExplSyntaxOn

\seq_new:N \g_tikz_labelcache_seq

\msg_new:nnn { TikZ } { label-defined } { Name~#1~already~defined! }

\NewDocumentCommand \checklabelname { m }
{
  \seq_if_in:NoTF \g_tikz_labelcache_seq { #1 }
    { \msg_error:nnx { TikZ } { label-defined } { #1 } }
    { \seq_gpush:No \g_tikz_labelcache_seq { #1 } }
}

\NewDocumentCommand \resetlabellist { }
{
  \seq_gclear:N \g_tikz_labelcache_seq
}

\ExplSyntaxOff

\makeatletter
\protected\def\tikz@fig@main#1{%
  \checklabelname{\tikz@fig@name}%
  \iftikz@node@is@pic%
    \tikz@node@is@picfalse%
    \tikz@subpicture@handle{#1}%
  \else%
    \tikz@@fig@main#1\egroup%
  \fi}

% Reset list at end of picture to prevent carrying names over
\g@addto@macro\endtikzpicture{\resetlabellist}

\makeatother

\begin{document}

\begin{tikzpicture}
  \node (B) {}; 
\end{tikzpicture}

\begin{tikzpicture}
  \node (A) {}; 
  \node (B) {}; 
  \node (A) {}; 
\end{tikzpicture}

\end{document}

相关内容