В моемпредыдущий пост, я спросил, как использовать два цикла для построения сетки со значениями внутри нее. Замечательныйотвечать был данЭндрю Суонн.
\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 and
less to separate into two cases, and the
min function inside the
greater`, чтобы определить, какие столбцы должны содержать ноль.