Странное поведение \foreach

Странное поведение \foreach

Я наблюдаю странное поведение при использовании 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}

Если вы закомментируете строки между «start weirdness» и «end weirdness» и раскомментируете последние пять строк, вы увидите, что проблема чудесным образом устранена: все строки выглядят одинаково.

Теперь все линии одинаковой длины.

Опять же, в исходном коде --- и соответствующей картинке в верхней части этого поста --- желаемое поведение — более короткая строка. Остальные три нежелательны. Можете ли вы помочь мне получить желаемое поведение?

Спасибо!

решение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

ТикZ не нужно анализировать выражение и не добавляет .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, т.е. вы можете обнаружить другие "странности", если используете циклы calcс \x. И если вы хотите, чтобы пробелы исчезли, вы можете просто нарисовать узлы с помощью TiкЗ.

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

введите описание изображения здесь

Стивен Б. Сегелец предлагает использовать\the\numexprevaluate. Это работает хорошо, но тогда вам это вообще не нужно .

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

введите описание изображения здесь

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