使用 foreach 循环从 0 开始,第一个索引不是整数

使用 foreach 循环从 0 开始,第一个索引不是整数

我正在尝试使用 tikzpicture 绘制一棵树,如下所示:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{math}
\begin{document}
\begin{tikzpicture}
    \tikzstyle{node}=[circle, fill=blue!25, minimum size=0.1 cm];
    \foreach \ilayer in {0,...,3} {
        \tikzmath {\nnodes = 3 ^ \ilayer; }
        \tikzmath {\leftnum = 1 - floor(\nnodes / 2) - 1; }
        \tikzmath {\rightnum = \nnodes - floor(\nnodes / 2) - 1; }
        \foreach \isibling in {\leftnum,...,\rightnum} {                
            \tikzmath {\d = 3 ^ (- \ilayer) * 15; }
            \tikzmath {\x = \isibling * \d; }
            \tikzmath {\y = - \ilayer * 2; }
            \node[node] (node_\ilayer_\isibling) at (\x cm, \y cm) {\isibling};
        }
    }
\end{tikzpicture}
\end{document}

我得到了如下图所示的树。文本是\isibling每一层内的节点。大多数节点都是整数,但所有最左边的节点都不是整数。

在此处输入图片描述

答案1

你可以告诉 TiZ 明确表示你想要一个整数。

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{math}
\begin{document}
\begin{tikzpicture}
    \tikzset{mynode/.style={circle, fill=blue!25, minimum size=0.1 cm}}
    \foreach \ilayer in {0,...,3} {
        \tikzmath {\nnodes = 3 ^ \ilayer; }
        \tikzmath {\leftnum = int(1 - floor(\nnodes / 2) - 1); }
        \tikzmath {\rightnum = \nnodes - floor(\nnodes / 2) - 1; }
        \foreach \isibling in {\leftnum,...,\rightnum} {                
            \tikzmath {\d = 3 ^ (- \ilayer) * 15; }
            \tikzmath {\x = \isibling * \d; }
            \tikzmath {\y = - \ilayer * 2; }
            \node[mynode] (node_\ilayer_\isibling) at (\x cm, \y cm) {\isibling};
        }
    }
\end{tikzpicture}
\end{document}

在此处输入图片描述

或者

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{math}
\begin{document}
\begin{tikzpicture}
    \tikzset{mynode/.style={circle, fill=blue!25, minimum size=0.1 cm}}
    \foreach \ilayer in {0,...,3} {
        \tikzmath {int \nnodes,\leftnum,\rightnum;
            \nnodes = 3 ^ \ilayer;
            \leftnum = 1 - floor(\nnodes / 2) - 1; 
        \rightnum = \nnodes - floor(\nnodes / 2) - 1; }
        \foreach \isibling in {\leftnum,...,\rightnum} {                
            \tikzmath {\d = 3 ^ (- \ilayer) * 15; 
            \x = \isibling * \d; 
            \y = - \ilayer * 2; }
            \node[mynode] (node_\ilayer_\isibling) at (\x cm, \y cm) {\isibling};
        }
    }
\end{tikzpicture}
\end{document}

原则上,这里不需要数学库。

\documentclass[tikz,border=3.14mm]{standalone}
\begin{document}
\begin{tikzpicture}
    \tikzset{mynode/.style={circle, fill=blue!25, minimum size=0.1 cm}}
    \foreach \ilayer [evaluate=\ilayer as \nnodes using {int(3 ^ \ilayer)},
    evaluate=\nnodes as \leftnum using {int(1 - floor(\nnodes / 2) - 1)},
    evaluate=\nnodes as \rightnum using {int(\nnodes - floor(\nnodes / 2) - 1)}]
    in {0,...,3} {
        \foreach \isibling 
        [evaluate=\ilayer as \d using {3 ^ (- \ilayer) * 15},
        evaluate=\isibling as \x using {\isibling * \d},
        evaluate=\ilayer as \y using {- \ilayer * 2}]
        in {\leftnum,...,\rightnum} {                
            \node[mynode] (node_\ilayer_\isibling) at (\x cm, \y cm) 
            {\isibling};
        }
    }
\end{tikzpicture}
\end{document}

在此处输入图片描述

答案2

正如 @marmot 所说,你在这里不需要tikzmath,但如果你使用它,你可以用更有效的方式做到这一点:

  • 您可以使用一个\tikzmath包含循环的命令。
  • 您可以声明您的整数变量,这样int您之后就不需要再做任何事情了int()
  • 奇怪的是,\nnodes您不需要\rightnum分开;\leftnum\rightnum = - \leftnum
  • 为什么使用1-floor(\nnodes/2)-1代替-floor(\nnodes/2)
  • 该值\d可以在外循环中计算。
  • 除了使用之外,\x=\isibling*\d您还可以说[x=\d cm],然后使用\isiblingas \x。同样,也可以通过使用\y来替换。\ilayer[y=-2cm]

因此,这是我的建议:

\documentclass[tikz,border=7pt]{standalone}
\usetikzlibrary{math}
\begin{document}
\begin{tikzpicture}
  \tikzstyle{node}=[circle, fill=blue!25, minimum size=0.1 cm];
  \tikzmath{
    int \ilayer,\nnodes,\rightnum,\isibling;
    \nnodes = 1;
    for \ilayer in {0,...,3}{
      \rightnum = (\nnodes-1)/2;
      \d = 15/\nnodes;
      for \isibling in {-\rightnum,...,\rightnum}{
        {
          \path[x=\d cm,y=-2cm]
            node[node] (node_\ilayer_\isibling) at (\isibling, \ilayer) {\isibling};
        };
      };
      \nnodes = 3*\nnodes;
    };
  }
\end{tikzpicture}
\end{document}

在此处输入图片描述

相关内容