在 Tikz 循环中使用数组进行读写

在 Tikz 循环中使用数组进行读写

在循环中使用数组的正确方法是什么\foreach?我试图说明汉诺塔问题。我有一组“磁盘大小”/“杆”对序列,我的代码应该按照我的序列在放置在那里的杆上绘制磁盘。但是,数组似乎存在一些问题(我使用arrayjobx包,但如果更合适,我很乐意切换到其他技术)。

\documentclass{article}
\usepackage{tikz}
\usepackage{arrayjobx}

\begin{document}
\def\sequence{4/1,3/2,2/1,1/2}
\begin{tikzpicture} 
    \newarray\last

    % Initialise \last and print the rod indices
    \foreach \rod in {1, 2}{
        \last(\rod)={0};
        \node at (5 * \rod, -1) {\rod};
    }

    \foreach \size/\rod in \sequence{
        % Load \last(\rod) in variable \y
        \checklast(\rod);
        \let\l\cachedata;
        \xdef\y{\l};

        % Update \last(\rod)
        \last(\rod)={\y + 1};

        % Draw the disk
        \draw[ultra thick] (5*\rod - 0.5*\size, \y)--(5*\rod + 0.5*\size, \y);
    }
\end{tikzpicture}
\end{document}

我得到以下结果:

在此处输入图片描述

而预期的是:

在此处输入图片描述

汉诺塔只是一个玩具例子;关键是我的实际情况需要在\foreach循环内对几个数组进行非连续的读写。

答案1

我定义了三个宏:

  • \gset: 表示“全局集”。使用方法如下\gset data[2]=3
  • \get: 表示“获取”。使用方法如下\get data[2]
  • \ginc: 表示“全局增量”。使用方法如下\ginc data[1]+=2

使用示例:

\documentclass[tikz,border=7mm]{standalone}
  % set the value
  \def\gset #1[#2]=#3{%
    \expandafter\xdef\csname #1#2\endcsname{#3}
  }
  % get the value
  \def\get #1[#2]{%
    \csname #1#2\endcsname
  }
  % increment the value
  \def\ginc #1[#2]+=#3{%
    \pgfmathparse{\get #1[#2]+#3}%
    \gset #1[#2]=\pgfmathresult
  }

\begin{document}
  % the sequence
  \def\sequence{7/1,6/3,5/1,4/1,3/2,2/3,1/3}

  \begin{tikzpicture}[line width=4mm, line cap=round,xscale=3,brown!30]
    % init colors
    \foreach[count=\j] \c in {red,green,blue,orange,pink,purple,gray}
      \gset col[\j]={\c};
    \edef\numdisks{\j}
    % init positions and draw support
    \foreach \j in {1,2,3}{
      \gset pos[\j]=0
      \draw (\j,-.5) -- +(0,3);
    }
    \draw (.5,-.5) -- +(3,0);

    % draw
    \foreach[count=\k] \i/\j in \sequence{
      \draw[draw={\get col[\i]}] (\j,\get pos[\j]) +(-.4*\i/\numdisks,0) -- +(.4*\i/\numdisks,0);
      \ginc pos[\j]+={.5}
    }
  \end{tikzpicture}
\end{document}

在此处输入图片描述

答案2

感谢您的评论。在您的帮助下,我设法弄清楚了如何使用 \csname 机制实现这一点:

\documentclass{article}
\usepackage{tikz}

\begin{document}

\def\sequence{4/1,3/2,2/1,1/2}

\begin{tikzpicture} 
    % Initialise "last" and print the rod indices
    \foreach \rod in {1, 2}{
        \expandafter\xdef\csname last@array@\rod\endcsname{0}
        \node at (5 * \rod, -1) {\rod};
    }   

    \foreach \size/\rod in \sequence{
        % Load last[\rod] in variable \y
        \pgfmathparse{\csname last@array@\rod\endcsname}
        \let\y=\pgfmathresult

        % Update last[\rod]
        \pgfmathparse{\y + 1}
        \let\newy=\pgfmathresult;
        \expandafter\xdef\csname last@array@\rod\endcsname{\newy};

        % Draw the disk
        \draw[ultra thick] (5*\rod - 0.5*\size, \y)--(5*\rod + 0.5*\size, \y);
    }
\end{tikzpicture}
\end{document}

相关内容