Comportamento estranho de \foreach

Comportamento estranho de \foreach

Estou tendo um comportamento estranho ao usar o TikZAvaliesintaxe.

Por que o resultado final é mais curto do que os outros três?

Veja como a linha diagonal inferior é mais curta que as outras três? Este não é o comportamento desejado. O código da imagem acima está aqui:

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

Se você comentar as linhas entre "iniciar estranheza" e "terminar estranheza" e descomentar as últimas cinco linhas, verá que o problema foi resolvido magicamente: todas as linhas parecem iguais.

Agora todas as linhas têm o mesmo comprimento.

Novamente, no código original — e na imagem associada no topo desta postagem — o comportamento desejado é a linha mais curta. Os outros três são indesejáveis. Você pode me ajudar a obter o comportamento desejado?

Obrigado!

Responder1

Conforme escrito no meu comentário, você precisa \x+1envolverint

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

caso contrário, você obterá números como 2.0, onde .0é interpretado como uma âncora. .0é (neste caso) coincidente com a âncora leste, ou seja, no ângulo 0. Sua saída mostra linhas que se conectam à âncora leste dos respectivos Ynós do tipo. Você pode estar se perguntando por que o problema não acontece no segundo loop. Isso ocorre porque quando você diz

 evaluate=\x as \sx using \x

TikZ não precisa analisar a expressão e não adiciona .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}

insira a descrição da imagem aqui

Aliás, eu evitaria usar \xcomo variável de loop, já que ela também é usada por calc, ou seja, você pode encontrar outras "estranhezas" se usar calccom \xloops. E se você quiser que as lacunas desapareçam, você pode simplesmente desenhar os nós com TikZ.

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

insira a descrição da imagem aqui

Steven B. Segelets sugere usar\the\numexpr. Isso funciona bem, mas você não precisa evaluatede nada.

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

Responder2

Tenho certeza que existe uma tikzmaneira de fazer isso, mas concluí a \x+1avaliação necessária, então como é integral, usei \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}

insira a descrição da imagem aqui

informação relacionada