我想要一个很长的项目列表,每个项目都是一个列表 {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}
答案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}