Использование условия (If/Else) внутри цикла (For) в Tikz

Использование условия (If/Else) внутри цикла (For) в Tikz

В моемпредыдущий пост, я спросил, как использовать два цикла для построения сетки со значениями внутри нее. Замечательныйотвечать был данЭндрю Суонн.

\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) прежде \z, чем я смогу распечатать вывод, как я показал выше?

решение1

Вы можете легко использовать ifthenelse в узле tikz:

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

решение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(89.3.5 Сравнение и логические функции в руководстве 3.0.1a), например, equal(x,y)which возвращает , 0если xи yне равны, а в противном случае возвращает 1, и greater(x,y)which возвращает , 1если x>yи в противном случае 0и включите их в свою evaluateинструкцию вместе с функциями minи max.

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

Кусочная природа вводится посредством использования функций notlessи greater, действующих как множители фактического числа, представляющего интерес, которые имеют тот же эффект, что и условные операторы, которые вы искали.

Можно представить себе более общий случай, который описывает ваш второй случай, в котором печатаются все числа вплоть до некоторой строки, в которой они \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`, чтобы определить, какие столбцы должны содержать ноль.

Связанный контент