这是在询问以下方面的意见和经验
- 是否应该避免(出于我想不出的严重原因)在同一个 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}