tikz:变量名中没有 pgf 宏的数学表达式

tikz:变量名中没有 pgf 宏的数学表达式

请考虑下图:

在此处输入图片描述

我希望能够计算变量名中的数学表达式。例如,我希望能够写入(a$\i+1$\j)以下代码来生成上述输出:

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}

\begin{tikzpicture}[>=to]
  \node (a) at (0,0) {};
  \foreach \i in {0,1,2,3}
     \foreach \j in {0,1,2}
        \node (a\i\j) at ($(a) + (\i, -\j)$) {};

  \foreach \i in {0,1,2}
     \foreach \j in {0,1,2}
        \draw[->] (a\i\j) -- (a$\i+1$\j);

  \foreach \i in {0,1,2,3}
     \foreach \j in {0,1}
        \draw[->,dotted] (a\i\j) -- (a\i$\j+1$);
\end{tikzpicture}

\end{document}

有没有办法在不使用 pgfmathsetmacro 和 pgfmathtruncatemacro 等 pgf 宏的情况下实现此功能,这些宏感觉有点不靠谱?另外,有没有更好的方法来生成图表?

答案1

您可以使用count-loop 函数foreach。与ifnum此结合使用非常强大,而且非常神奇。这样,您还可以将所有代码放入一个循环中,并节省一些编译时间。

请参阅以下代码:

\documentclass[tikz, border=5mm]{standalone}

\begin{document}
 \begin{tikzpicture}
  \foreach \x [count=\xx from -1] in {0,...,3} {
   \foreach \y [count=\yy from -1] in {0,...,3} {
    \node (a\x\y) at (\x,-\y) {};
    \ifnum\xx>-1
     \draw [->] (a\xx\y) -- (a\x\y);
    \fi        
    \ifnum\yy>-1
     \draw [->, dotted] (a\x\yy) -- (a\x\y);
    \fi
   }
  }  
 \end{tikzpicture}
\end{document}

渲染图像

答案2

您可以尝试使用evaluate的选项\foreach,但我更喜欢使用更简单的方法\pgfmathtruncatemacro来执行算术计算:

在此处输入图片描述

代码:\pgfmathtruncatemacro

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}

\begin{tikzpicture}[>=to]
  \node (a) at (0,0) {};
  \foreach \i in {0,1,2,3}
     \foreach \j in {0,1,2}
        \node (a\i\j) at ($(a) + (\i, -\j)$) {};

  \foreach \i in {0,1,2}
     \pgfmathtruncatemacro{\IncrementI}{\i+1}%
     \foreach  \j in {0,1,2}
        \draw[->] (a\i\j) -- (a\IncrementI\j);

  \foreach \i in {0,1,2,3}
     \foreach \j in {0,1}
     \pgfmathtruncatemacro{\IncrementJ}{\j+1}%
        \draw[->,dotted] (a\i\j) -- (a\i\IncrementJ);
\end{tikzpicture}

\end{document}

代码:evaluate

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}

\begin{tikzpicture}[>=to]
  \node (a) at (0,0) {};
  \foreach \i in {0,1,2,3}
     \foreach \j in {0,1,2}
        \node (a\i\j) at ($(a) + (\i, -\j)$) {};

  \foreach [evaluate={\IncrementI=int(\i+1)}] \i in {0,1,2}
     \foreach  \j in {0,1,2}
        \draw[->] (a\i\j) -- (a\IncrementI\j);

  \foreach \i in {0,1,2,3}
     \foreach [evaluate={\IncrementJ=int(\j+1)}] \j in {0,1}
        \draw[->,dotted] (a\i\j) -- (a\i\IncrementJ);
\end{tikzpicture}

\end{document}

答案3

$我们可以破解坐标解析器,这样 OP 所需的语法就成为可能。如果calc库已加载,这仅适用于不以 开头的命名坐标,并且如果 的类别代码$发生更改(例如,变为活动状态),则根本不可能起作用:

\documentclass[tikz,border=5]{standalone}
\makeatletter
\let\tikz@@parse@node=\tikz@parse@node    
\def\tikz@parse@node#1(#2){%
  \pgfutil@in@{$}{#2}%$
  \ifpgfutil@in@%
    \let\tikz@next=\tikz@parse@node@calc%
  \else%
    \let\tikz@next=\tikz@@parse@node%
  \fi%
  \tikz@next{#1}(#2)%    
}    
\def\tikz@parse@node@calc#1(#2$#3$#4){%
  \pgfmathparse{\tikzcoordinatefunction{#3}}%
  \edef\tikz@tmp{#2\pgfmathresult#4}%
  \def\tikz@marshal{\tikz@parse@node{#1}}%
  \expandafter\tikz@marshal\expandafter(\tikz@tmp)%
}    
\def\tikzcoordinatefunction#1{int(#1)}    
\begin{document}    
\begin{tikzpicture}
 \foreach \i in {1,...,4}
   \foreach \j in {1,...,4}
     \node (a\i\j) at (\j, -\i) {};    
\foreach \i in {1,...,4}
  \foreach \j in {1,...,3}
    \draw [->] (a\i\j) -- (a\i$\j+1$);    
\foreach \i in {1,...,3}
  \foreach \j in {1,...,4}
    \draw [->, dotted] (a\i\j) -- (a$\i+1$\j);
\end{tikzpicture}    
\end{document}

在此处输入图片描述

相关内容