我的问题很简单,我也有解决方案。但我希望有一个更好的解决方案:)考虑以下代码:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
\foreach \x in {1,2,3} {
\coordinate (V\x) at ($(\x-1,0)$);
}
\foreach \x in {1,2} {
\draw[black] ($(V\x)$) -- ($(V{\x+1})$);
}
\end{tikzpicture}
\end{document}
在第一个\foreach
循环中,计算\x+1
工作正常,但是在第二个循环中,问题是$(V{\x+1})$
扩展为V{1+1}
而不是V2
..我希望有办法避免定义另一个变量来解决这个问题..我知道我可以通过写作来解决这个问题
\foreach \x in {1,2} {
\pgfmathtruncatemacro{\y}{\x+1};
\draw[black] ($(V\x)$) -- ($(V\y)$);
}
但我觉得这有点过度了:) 。有没有办法避免\pgfmathtruncatemacro
在这里使用?
答案1
下面的方法应该可以解决问题。您可以计算值并将其分配给宏。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
\foreach \x in {1,2,3} {
\coordinate (V\x) at ($(\x-1,0)$);
}
\foreach \x [evaluate=\x as \sx using int(\x+1)] in {1,2} {
\draw[black]
($(V\x)$) -- ($(V\sx)$);
}
\end{tikzpicture}
\end{document}
答案2
首先我想说,Marc 的解决方案是解决这个问题的正确方法,但我认为解释一下为什么需要解决方案可能会有所帮助。
TikZ 非常擅长将东西发送到它的数学解析器,这意味着你可以使用表达式指定坐标。对于更复杂的东西,有一个 calc 库。但在某些情况下它不会期望表达式,因此它不必理会解析器。其中之一就是节点名称。由于名称本身不被认为具有任何语义含义,因此在解析器中没有合理的方法来解释它们。因此,节点V1
只是两个符号的名称,与节点没有隐含的关系V2
。所以当它遇到时V{1+1}
,TikZ 没有逻辑告诉它你真正的意思是V2
。简而言之,节点名称不会被解析为数学表达式。
但是,节点名称扩展。也就是说,由于节点名称只是一个字符串,因此 TikZ 会传递节点名称edef
以尝试扩展其中的任何宏。这就是为什么V\x
和V\sx
能起作用。
不幸的是,PGF 的数学解析器不可扩展,这就是为什么必须先进行计算 - 要么隐式(如 Marc 的解决方案)要么显式(如您的解决方案) - 然后将结果插入存储在可扩展宏中的节点名称中。但还有其他可扩展的数学解析器可以在此上下文中使用。特别是,原语\numexpr
会扩展(当以 为前缀时\the
),因此:
\documentclass{article}
%\url{http://tex.stackexchange.com/q/101134/86}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
\foreach \x in {1,2,3} {
\coordinate (V\x) at ($(\x-1,0)$);
}
\foreach \x in {1,2} {
\draw[black] (V\x) -- (V\the\numexpr\x+1\relax);
}
\end{tikzpicture}
\end{document}
作品。
但正如我在开始时所说的那样,Marc 的解决方案在这里更好,因为它不混合方法:所有计算都是由 TikZ/PGF 完成的,因此可以确保一致性。