在 Tikz 中的循环(For)中使用条件(If/Else)

在 Tikz 中的循环(For)中使用条件(If/Else)

在我的上一篇,我问过如何使用两个循环来构造一个带有值的网格。一个精彩的回答 给出的是安德鲁·斯旺

\documentclass{article}

\usepackage{tikz}

\begin{document}

\def\n{6}
\def\m{8}
\def\s{1.5cm}
\tikz\draw grid[step=\s](\n*\s,\m*\s) foreach[evaluate] \x  in {1,...,\n}
  { foreach[evaluate={\z = int(min(\x,\n+1-\x)+\n*min(\y-1,\m-\y)/2)}] \y in {1,...,\m}
  {({\s*(.5+(\x-1))},{\s*(\m+.5-\y)}) node{$a=\z$}}};

\end{document}

他提供了一个\z可以根据不同的价值观排列进行修改的公式。

例如,我做过-

[评估= {\z = int(\x+\n*min(\y-1,\m+\y))}]

这使-

1 2 3 4

5 6 7 8

9 10 11 12

3*4 网格。但如果我想要 -

1 2 2 1

3 4 4 3

5 6 6 5

7 8 8 7

和 ,

1 2 3 4

5 6 7 8

0 9 10 0

0 11 12 0

0 13 14 0

我做不到!我真的很难使用循环和 if else 条件。可能是我太习惯 C++ 和类似的东西了,我可以轻松地做 a=a+1 或写 if 条件。我能想到一种打印上述值排列的方法,使用健康)状况(if/else),但我不知道把它放在哪里(我试过,但都是错的)。

所以我的问题是,如何健康)状况(if/else)之前,\z以便我可以打印输出,如上所示?

答案1

您可以在 tikz 节点中轻松使用 ifthenelse:

\documentclass{minimal}
\usepackage{tikz}
\usepackage{ifthen}

\begin{document}

\def\n{4}
\def\m{4}
\def\s{1.5cm}
\tikz\draw grid[step=\s](\n*\s,\m*\s) 
  foreach[evaluate] \x  in {1,...,\n} { 
    foreach[evaluate={
      \zt = int(\x+\n*min(\y-1,\m+\y));
      \zb = int(\x+(\n-2)*min(\y-1,\m+\y)+3)
    }] \y in {1,...,\m} {
      ({\s*(.5+(\x-1))},{\s*(\m+.5-\y)}) node{$a=\ifthenelse{\y>2}{\ifthenelse{\x=1 \OR \x>3}{0}{\zb}}{\zt}$}
    }
  };

\end{document}

这将创建您想要的第三个网格。

另请参阅以下问题的答案以获取更多带有 ifthenelse 和循环的示例: TikZ 图内的 If-then-else?

答案2

您可以在 TikZ 中使用“条件赋值”语句,您可能从 C 语言中知道这个语句。语法是result = cond?v0:v1。如果条件cond为真,v0则将赋值给result,否则v1赋值给。

此表达式可用作evaluate代码中键的一部分。此外,该表达式可嵌套在另一个条件赋值中,例如:result = cond1?(cond2?v0:v1):v2

因此,就您而言(代码改编自 val 的答案):

\documentclass[border=1cm]{standalone}
\usepackage{tikz}

\begin{document}

\def\n{4}
\def\m{4}
\def\s{1.5cm}
\noindent\tikz\draw grid[step=\s](\n*\s,\m*\s) 
  foreach[evaluate] \x  in {1,...,\n} { 
    foreach[evaluate={
      \zt = int(\x+\n*min(\y-1,\m+\y));
      \zb = int(\x+(\n-2)*min(\y-1,\m+\y)+3);
      \zr = \y>2?((\x==1)||(\x>3)?0:\zb):\zt     % <-------- see here
    }] \y in {1,...,\m} {
      ({\s*(.5+(\x-1))},{\s*(\m+.5-\y)}) node{\zr}
    }
  };

\end{document}

其结果为:

结果

答案3

可以使用比较/逻辑数学函数pgf(3.0.1a 手册中的 89.3.5 比较和逻辑函数)例如,如果和不相等则equal(x,y)返回,否则返回,以及如果和否则则返回,并将它们与和函数一起合并到您的指令中。0xy1greater(x,y)1x>y0evaluateminmax

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

\begin{document}
\def\n{4}
\def\m{6}
\def\blnk{1}
\def\mx{8}
\def\s{1.5cm}
\tikz\draw grid[step=\s](\n*\s,\m*\s) foreach \x  in {1,...,\n}
  { foreach[evaluate={\z = int(divide(\n,2)*(\y-1)+min(\x,\n+1-\x))}] \y in {1,...,\m}
  {({\s*(.5+(\x-1))},{\s*(\m+.5-\y)}) node{$a=\z$}}};
\tikz\draw grid[step=\s](\n*\s,\m*\s) foreach \x  in {1,...,\n}
  { foreach[evaluate={\z = int(notless(\n*(\y-1),\mx)*greater(min(\x-\blnk,\n+1-\x-\blnk),0)*((\n-2*\blnk)*(\y-ceil(divide(\mx,\n))-1)  +\x-\blnk+\n*ceil(divide(\mx,\n)))+less(\n*(\y-1),\mx)*(\n*(\y-1)+\x))}] \y in {1,...,\m}
  {({\s*(.5+(\x-1))},{\s*(\m+.5-\y)}) node{$a=\z$}}};
\end{document}

在此处输入图片描述

对于您的第一个例子,该函数int(divide(\n,2)*(\y-1)+min(\x,\n+1-\x))似乎符合您的第一个例子,实际上并不需要任何条件,只min需要具有适当的+\x-\x项的函数。

分段性质是通过使用notlessgreater函数作为实际感兴趣的数字的乘数来引入的,它们具有与您所追求的条件相同的效果。

我们可以想象一个更普遍的情况来描述你的第二种情况,它打印出所有的数字,直到出现某些行,之后它在两边\mx放置一些零作为填充,同时仍然不断增加,函数似乎可以完成这项工作,向上舍入到最接近的整数。\blnkint(notless(\n*(\y-1),\mx)*greater(min(\x-\blnk,\n+1-\x-\blnk),0)*((\n-2*\blnk)*(\y-ceil(divide(\mx,\n))-1)+\x-\blnk+\n*ceil(divide(\mx,\n)))+less(\n*(\y-1),\mx)*(\n*(\y-1)+\x))ceil

对于仅表示您想要的函数的更简单情况int(notless(\y,3)*greater(min(\x-1,\n-\x),0)*((\n-2)*(\y-3)+\x+7)+less(\y,3)*(4*(\y-1)+\x)),再次使用notless andless to separate into two cases, and themin function inside thegreater` 函数来确定哪些列应该为零。

相关内容