%20%E5%85%A7%E7%9A%84%E6%A2%9D%E4%BB%B6%20(If%2FElse).png)
在我的上一篇文章,我問如何使用兩個循環來建構一個網格,其中包含值。一個完美的回答 是由安德魯·斯旺。
\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
您可以輕鬆地在 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 比較和邏輯函數)例如,if和不相等則equal(x,y)
返回,否則返回,以及if和 else 則返回,並將它們與和函數一起合併到您的指令中。0
x
y
1
greater(x,y)
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` 函數來確定哪些列應該為零。