tikz-pgf 中的数组元素访问

tikz-pgf 中的数组元素访问

我想要一个很长的项目列表,每个项目都是一个列表 {x,y,a,b},其中 (x,y) 指定放置点的点,其他项目与如何处理这个点有关。我期望

\def\elts{
  {14,6,3,3},    
  {14,2,100,1}    
}

\foreach \e in \elts
  \draw [fill] (\e[0],\e[1]) circle [radius=0.05];

会将实心圆放在 (14,6) 和 (14,2) 处。但实际上,它们位于 (13,5) 和 (14,2) 处。使用这种方法,我得到了各种错误的结果,没有合理的模式。显然 \e[2] 和 \e[3] 会影响结果。这是怎么回事?我以为 \foreach 会设置 \e = {14,6,3,3},访问其中的前两个元素,然后设置 \e = {14,2,100,1} 并访问其中的前两个元素。但事实并非如此。

这是一个小型的工作(失败)样本,其中有网格和编号,以便于查看问题。

\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}

\draw[color=lightgray] (8,0) grid [step=4]  (16,8);

\foreach \n in {8,12,16}
\node [below] at (\n,0) {$\n$};

\foreach \s in {0,4,8}
\node [left] at (8,\s) {$\s$};

\def\elts{
{14,6,3,3},     %% Should produce a dot at (14,6), not at (13,5) 
{16,4,15,8},    %% Try changing the 15 to a 7 for puzzlement.
{14,2,100,1}    %% (14,2) as intended
}

\foreach \e in \elts
\draw [fill] (\e[0],\e[1]) circle [radius=0.05];

\end{tikzpicture}
\end{document}

这是我在 OS X 10.11.6 上使用 TeXShop 3.62 产生的结果。 点应该位于 (14,6)、(16,4) 和 (14,2)。但实际上它们位于 (13,5)、(10,-2​​) 和 (14,2)

答案1

不出所料,“错误”结果来自错误的语法。您有额外的空格,并且数组需要额外的括号。我在定义时添加了它们\mye,但您也可以在其他情况下添加它们。

\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}

\draw[color=lightgray] (8,0) grid [step=4]  (16,8);

\foreach \n in {8,12,16}
\node [below] at (\n,0) {$\n$};

\foreach \s in {0,4,8}
\node [left] at (8,\s) {$\s$};

\def\elts{% see all the % I added to kill spaces
{14,6,3,3},%     %% Should produce a dot at (14,6), not at (13,5) 
{16,4,15,8},%    %% Try changing the 15 to a 7 for puzzlement.
{14,2,100,1}%    %% (14,2) as intended
}

\foreach \e in \elts
{\edef\mye{{\e}}
\pgfmathsetmacro{\myx}{\mye[0]}
\pgfmathsetmacro{\myy}{\mye[1]}
\draw [fill] (\myx,\myy) circle [radius=0.05];
}
\end{tikzpicture}
\end{document}

在此处输入图片描述

请注意,你可以使代码更清晰,但随后你就失去了交叉检查中间步骤的能力,而且更有可能责怪 Ti如果出错,则为 Z。无论如何,这里有一个更清晰的变体。

\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}

\draw[color=lightgray] (8,0) grid [step=4]  (16,8);

\foreach \n in {8,12,16}
\node [below] at (\n,0) {$\n$};

\foreach \s in {0,4,8}
\node [left] at (8,\s) {$\s$};

\def\elts{%
{{14,6,3,3}},%     %% Should produce a dot at (14,6), not at (13,5) 
{{16,4,15,8}},%    %% Try changing the 15 to a 7 for puzzlement.
{{14,2,100,1}}%    %% (14,2) as intended
}

\foreach \e in \elts
{
\draw [fill] ({\e[0]},{\e[1]}) circle [radius=0.05];
}
\end{tikzpicture}
\end{document}

答案2

宏中的新行\elts会导致空格,这在 tex 中很常见。除了最后一行之外,每行都以逗号结尾,并\foreach会自动占用条目中的初始空格,但最后的新行会在条目中添加一个尾随空格。添加%可隐藏此空格。

当宏的整个参数都用括号括起来时,tex 会去掉括号,因此每个列表周围的括号都会被去掉,因此您需要重新添加一对括号。(我们之所以担心尾随空格,是因为最后一个条目中的尾随空格会阻止 tex 从最后一个条目中删除括号,从而导致不一致的括号)。

\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}

\draw[color=lightgray] (8,0) grid [step=4]  (16,8);

\foreach \n in {8,12,16}
\node [below] at (\n,0) {$\n$};

\foreach \s in {0,4,8}
\node [left] at (8,\s) {$\s$};

\def\elts{
{8,0},
{14,6,3,3},
{16,4,7,8},
{14,2,100,1}% Prevent terminal space so the braces from last entry aren't stripped
}

\foreach\e in \elts
\draw [fill] ({\e}[0],{\e}[1]) % Put the stripped braces back
      circle [radius=0.05];

\end{tikzpicture}
\end{document} 

另一种可行的构造方法是确保每个条目都有一个尾随空格,这样 tex 就不会从一开始就删除坐标周围的括号:

\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}

\draw[color=lightgray] (8,0) grid [step=4]  (16,8);

\foreach \n in {8,12,16}
\node [below] at (\n,0) {$\n$};

\foreach \s in {0,4,8}
\node [left] at (8,\s) {$\s$};

% There is a space after each entry which prevents tex from removing
% any braces.
\def\elts{
{8,0} ,
{14,6,3,3} ,     %% Should produce a dot at (14,6), not at (13,5)
{16,4,7,8} ,    %% Try changing the 15 to a 7 for puzzlement.
{14,2,100,1}    %% (14,2) as intended
}

\foreach\e in \elts
% No need to replace the braces because they didn't get removed in the first place
\draw [fill] (\e[0],\e[1]) 
    circle [radius=0.05];

\end{tikzpicture}
\end{document} 

相关内容