Tikz でループ (For) 内で条件 (If/Else) を使用する

Tikz でループ (For) 内で条件 (If/Else) を使用する

私の前の記事2つのループを使って内部に値を持つグリッドを構築する方法を尋ねました。素晴らしい答え によって与えられたアンドリュー・スワン

\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}

これにより、必要な 3 番目のグリッドが作成されます。

ifthenelse とループのその他の例については、次の質問の回答も参照してください。 TikZ グラフ内の If-then-else ですか?

答え2

TikZ では、おそらく C 言語でご存じの「条件付き割り当て」文を使用できます。構文は ですresult = cond?v0:v1。条件condが true の場合は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適切な+\xand-\x項を持つ関数だけが必要です。

notless区分的な性質は、実際の関心のある数値に対する乗数として機能する関数と関数の使用によって導入されgreater、これは、求めていた条件文と同じ種類の効果を持ちます。

2 番目のケースを説明するより一般的なケースを想像することができます。これは、行に出現するまですべての数値を出力し\mx、その後、両側にパディングとしてゼロの数を配置しながら、関数が機能しているように見える\blnk連続的に増加し、最も近い整数に切り上げます。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))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` 関数を使用して、どの列にゼロを設定する必要があるかを識別します。

関連情報