在此问题我们使用很多可能性来定义立方体。一个想法是命名顶点。我想找到一些东西来自动创建这些名称。在问题的最后一个例子中,我使用了名为 000,010,...,111 的节点。现在我想将这些名称(或引用,我不知道英文中的确切术语是什么)转换为常规名称 A,B,...,H。为了实现这一点,我使用三个循环来获取二进制表示的 8 个数字。我将这些数字转换为十进制。从逻辑上讲,公式是,1+\x+2*\y+4*\z
但我想反转两个名称,因为我会得到 A、B、C、D 而不是 A、B、D、C,所以我使用了一个小技巧:
1+\x+2*\y+4*\z+\y*(\y-2*\x)
。
使用计数器cnt
和宏\Alph
没有问题,但是现在(这是我的问题) 我想避免使用计数器而用 来代替,\Alph
但\@Alph
出现了问题。
这段小代码有效
\makeatletter
\def\tmp{10}
\def\macro{\@Alph{\tmp}}
\macro
\begin{tikzpicture}
\node(\macro){\macro};
\draw (J)--++(5,1);
\end{tikzpicture}
我的主要代码也有效
\documentclass{scrartcl}
\usepackage{tikz}
\begin{document}
\newcounter{cnt}
\begin{tikzpicture}[ x={(-0.5cm,-0.5cm)}, y={(1cm,0cm)}, z={(0cm,1cm)},
every node/.style={shape=circle,draw}]
\foreach \z in {0,1}
\foreach \y in {0,1}
\foreach \x in {0,1}
{\pgfmathtruncatemacro{\nb}{1+\x+2*\y+4*\z+\y*(\y-2*\x)}
\setcounter{cnt} {\nb}
\node (\Alph{cnt}) at (4*\x,4*\y,4*\z) {\Alph{cnt}};
}%
\end{tikzpicture}
\end{document}
我想写一些类似的东西
错误代码
\documentclass{scrartcl}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[x={(-0.5cm,-0.5cm)}, y={(1cm,0cm)}, z={(0cm,1cm)},
every node/.style={shape=circle,draw}]
\foreach \z in {0,1}
\foreach \y in {0,1}
\foreach \x in {0,1}
{\pgfmathtruncatemacro{\nb}{1+\x+2*\y+4*\z+\y*(\y-2*\x)}
\makeatletter
\def\name{\@Alph{\nb}}
\node (\name) at (4*\x,4*\y,4*\z) {\name};
} %
\end{tikzpicture}
\end{document}
但我受到了很多侮辱,特别是:
Missing \endcsname inserted.
<to be read again>
\spacefactor
我的错误在哪里?
结果是一个未来的立方体:
答案1
从输入中读取字符时,其 catcode 是固定的。当\foreach
宏读取其参数时,的 catcode@
仍为“其他”,因为\makeatletter
在读取参数时未执行。当 TeX 处理 的扩展时\foreach
,它会发现\@
,这是一个扩展为 的宏\spacefactor \@m
,以及字符Alph
,这不是预期的。
\makeatletter
并且\makeatother
通常应该在宏之外使用。放在\def\name{\@Alph{\nb}}
序言中,代码就会起作用(当我评论说它有效时,我就是这么做的)。另外,\name
每次重新定义会比较慢。
如果坚持保留内部\def
,请\csname
明确调用\@Alph
:
\def\name{\csname @Alph\endcsname{\nb}}