奇怪的 \foreach[evaluate] 行為

奇怪的 \foreach[evaluate] 行為

使用 TikZ 時我遇到奇怪的行為評價句法。

為什麼底線比其他三條短?

看看底部的對角線比其他三條短嗎?這不是期望的行為。上圖的程式碼在這裡:

\documentclass{memoir}
\usepackage{tikz}
\begin{document}

\[
\begin{tikzpicture}
    \foreach \x in {0,...,4} 
        {\node (X\x) at (0,\x) {$\bullet$};
        }
    \foreach \x in {0,...,4} 
        {\node (Y\x) at (3,\x) {$\bullet$};
        }
% start weirdness
    \draw (X0) -- (Y1);
    \foreach \x [evaluate=\x as \sx using \x+1] in {1,...,3}
    {
        \draw (X\x) -- (Y\sx);
    }
% end weirdness. 
% Comment out the above weirdness and uncomment out the following:
%   \draw (X0) -- (Y0);
%   \foreach \x [evaluate=\x as \sx using \x] in {1,...,3}
%   {
%      \draw (X\x) -- (Y\sx);
%   }
\end{tikzpicture}
\]

\end{document}

如果您註解掉「開始怪異」和「結束怪異」之間的行,並且取消註解最後五行,您會發現問題被神奇地解決了:所有行看起來都一樣。

現在所有線的長度都相同。

同樣,在原始程式碼以及本文頂部的相關圖片中,所需的行為是較短的行。其他三個是不可取的。你能幫助我獲得所需的行為嗎?

謝謝!

答案1

正如我的評論中所寫,您需要將其\x+1納入int

\foreach \x [evaluate=\x as \sx using {int(\x+1)}] in {1,...,3}
    {
        \draw (X\x) -- (Y\sx);
    }

因為否則你會得到像這樣的數字2.0,其中.0被解釋為錨點。.0(在本例中)與東錨點重合,即角度為 0 Y。您可能想知道為什麼在第二個循環中沒有發生該問題。這是因為當你說

 evaluate=\x as \sx using \x

kZ 不需要解析表達式,且不新增.0.

\documentclass{memoir}
\usepackage{tikz}
\begin{document}

\[
\begin{tikzpicture}
    \foreach \x in {0,...,4} 
        {\node (X\x) at (0,\x) {$\bullet$};
        }
    \foreach \x in {0,...,4} 
        {\node (Y\x) at (3,\x) {$\bullet$};
        }
% start weirdness
    \draw (X0) -- (Y1);
    \foreach \x [evaluate=\x as \sx using {int(\x+1)}] in {1,...,3}
    {
        \draw (X\x) -- (Y\sx);
    }
\end{tikzpicture}   
\quad\mbox{vs.}\quad
\begin{tikzpicture}
% end weirdness. 
% Comment out the above weirdness and uncomment out the following:
    \foreach \x in {0,...,4} 
        {\node (X\x) at (0,\x) {$\bullet$};
        }
    \foreach \x in {0,...,4} 
        {\node (Y\x) at (3,\x) {$\bullet$};
        }
  \draw (X0) -- (Y0);
  \foreach \x [evaluate=\x as \sx using \x] in {1,...,3}
  {
     \draw (X\x) -- (Y\sx);
  }
\end{tikzpicture}
\]

\end{document}

在此輸入影像描述

順便說一句,我會避免使用\x作為循環變量,因為它也被使用,即如果您與循環一起calc使用,您可能會發現其他“怪異” 。如果你想讓間隙消失,你可以用 Ti 繪製節點calc\xkZ。

\documentclass{memoir}
\usepackage{tikz}
\begin{document}

\[
\begin{tikzpicture}[bullet/.style={circle,fill,inner sep=2pt}]
    \path foreach \Y in {0,...,4} 
        {(0,\Y) node[bullet] (X\Y){}
         (3,\Y) node[bullet] (Y\Y) {}
        };
    \foreach \X [evaluate=\X as \Y using {int(\X+1)}] in {0,...,3}
    {
        \draw (X\X) -- (Y\Y);
    }
\end{tikzpicture}   
\]
\end{document}

在此輸入影像描述

Steven B. Segelets 建議使用\the\numexpr。這工作正常,但你evaluate根本不需要。

\documentclass{memoir}
\usepackage{tikz}
\begin{document}

\[
\begin{tikzpicture}[bullet/.style={circle,fill,inner sep=2pt}]
    \path foreach \Y in {0,...,4} 
        {(0,\Y) node[bullet] (X\Y){}
         (3,\Y) node[bullet] (Y\Y) {}
        };
    \foreach \X  in {0,...,3}
    {
        \draw (X\X) -- (Y\the\numexpr\X+1);
    }
\end{tikzpicture}   
\]
\end{document}

答案2

我確信有一種tikz方法可以做到這一點,但我總結了\x+1所需的評估,因此由於它是不可或缺的,所以我使用了\numexpr.

\documentclass{memoir}
\usepackage{tikz}
\begin{document}

\[
\begin{tikzpicture}
    \foreach \x in {0,...,4} 
        {\node (X\x) at (0,\x) {$\bullet$};
        }
    \foreach \x in {0,...,4} 
        {\node (Y\x) at (3,\x) {$\bullet$};
        }
% start weirdness
    \draw (X0) -- (Y1);
    \foreach \x [evaluate=\x as \sx using \the\numexpr\x+1\relax] in {1,...,3}
    {
        \draw (X\x) -- (Y\sx);
    }
% end weirdness. 
% Comment out the above weirdness and uncomment out the following:
%   \draw (X0) -- (Y0);
%   \foreach \x [evaluate=\x as \sx using \x] in {1,...,3}
%   {
%      \draw (X\x) -- (Y\sx);
%   }
\end{tikzpicture}
\]

\end{document}

在此輸入影像描述

相關內容