2

I want to use foreach to draw connections between a sequence of nodes. But, for some reason, foreach forgets the position of the last node.

Here is an MWE illustrating my question: why are the two tikz figures different? As far as I can see, foreach used in the second figure should produce exactly the same code as in the first figure, where nodes are explicitly named. But it seems to forget updating the position of the last drawn node. Why?

Is there a way of producing the desired output (as in the first figure) using foreach? I don't want to use the coordinates, since I want the lines disconnected at nodes.

\documentclass{standalone}
\usepackage{tikz}

\begin{document}

    \begin{tikzpicture}
    \node (n1) at (0,0) {1};
    \node (n2) at (0,1) {2};
    \node (n3) at (1,1) {3};
    \node (n4) at (1,0) {4};
    \draw (n1) -- (n2) -- (n3) -- (n4);
    \end{tikzpicture}

    \begin{tikzpicture}
    \node (n1) at (0,0) {1};
    \node (n2) at (0,1) {2};
    \node (n3) at (1,1) {3};
    \node (n4) at (1,0) {4};
    \draw (n1) \foreach \i in {2,...,4} { -- (n\i)};
    \end{tikzpicture}
    
\end{document}
0
2

You can introduce a second counter into a foreach cycle by \i[count=\secondcounter]. Hence \secondcounter will assume as value the index of \i inside the set {2,...,4}. Thus \secondcounter has value 1,2,3 because the set {2,...,4} contains exactly three elements.

Notice that your foreach cycle draws segment always starting in (n1).

Anyway here the desired cycle:

\foreach \i[count=\x]  in {2,...,4}
{
\draw (n\x)  -- (n\i);
}

enter image description here

2
  • Thanks, this indeed solves my problem. But I still don't understand why my foreach draws segments always starting in (n1). I believed that foreach repeats only the body of the loop. Oct 27 '20 at 14:36
  • I think that \draw (n1) \foreach \i in {2,...,4} { -- (n\i)}; is equivalent to \foreach \i in {2,...,4} {\draw (n1) -- (n\i)};
    – Colo
    Oct 27 '20 at 18:58
0

The offending line is

\draw (n1) \foreach \i in {2,...,4} { -- (n\i)};

once expanded this gives the result

n1---n2 first iteration
n1---n3 second iteration
n1---n4 third iteration

whereas what is required is

n1---n2 first iteration
n2---n3 second iteration
n3---n4 third iteration

hence the necessity of the counter to increment n1 also

1
  • Thanks. I agree that this is what happens. But again, I don't understand why. I believed that foreach repeats the commands given in {}, in my case the part {-- (n\i)}. Anyway, I have code that works, so I'm letting this be, for now. Thanks again. Oct 27 '20 at 14:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.