I want to plot some dynamical systems with tikz but when I need to iterate on the node names, there is an error because the node name is broken when I need to work on the anchors.

I found multiple posts about accessing nodes in foreach calls such as this one but I could not find any dealing with the anchors.

Is there a specific way to protect the node name in the loop ?

\documentclass[tikz,border = 1mm]{standalone}
\usetikzlibrary{patterns,shapes.geometric,decorations.pathmorphing}
\def\bord{0.1cm}
\def\radius{.2cm}
\tikzset{
spring/.style={thick,decorate,decoration={
zigzag,
segment length = 1mm,
amplitude=0.7mm,
pre length=1mm,
post length=1mm}},
mass/.style={circle,minimum width=2*\radius,anchor=center}
}
\begin{document}
\begin{tikzpicture}[x=1cm,y=1cm,line join=round]
% Bord gauche
\fill [pattern = north east lines] (-.3,-2) rectangle (0,.5);
\draw[thick] (0,-2) -- (0,.5);

% Right edge
\def\borddroit{8}
\fill [fill=black!30!white] (\borddroit,-2) rectangle (\borddroit+.3,.5);
\fill [pattern = north east lines] (\borddroit,-2) rectangle (\borddroit+.3,.5);
\draw[ thick] (\borddroit,-2) -- (\borddroit,.5);

% Masses
\foreach \i in {1,2,...,6}{
    \node[mass,fill=blue] (m\i) at (\i,0) {};
}
\node[mass] (m0) at (0,0) {};
\node[mass,fill=red] (m7) at (7,0) {};

% Springs
% Working plot
\draw[spring] (m0.center) -- (m1.west);

% Working \foreach without anchor
\foreach \i in {0,...,6}{
   \pgfmathsetmacro{\j}{\i+1}
    \draw[spring] (m\i) -- (m\j) node[midway, above] (kuu\i) {$k$};
}


% Non working foreach beacause node name is broken
%\foreach \i in {0,...,6}{
%   \pgfmathsetmacro{\j}{\i+1}
%    \draw[spring] (m\i.east) -- (m\j.west) node[midway, above] (kuu\i) {$k^{\uu}$};
%}

\end{tikzpicture}
\end{document}
  • 3
    Untested, but use \pgfmathtruncatemacro not \pgfmathsetmacro, the latter makes a decimal value, so you get e.g. 1.0.west, instead of 1.west. – Torbjørn T. Aug 18 at 13:34
  • @TorbjørnT. It look soooo easy when you put it that way, feel free to post an answer so I can accept it ... Is there another way to compute \j say wihtout explicitly calling \pgfmathtruncatemacro ? – BambOo Aug 18 at 13:38
  • 2
    There are multiple duplicates around. You can use \foreach [evaluate={\j=int(\i+1)}] \i in {0,...,6} or \foreach [remember=\j as \i (initially 0)] \j in {1,...,7}. – Torbjørn T. Aug 18 at 13:41
up vote 6 down vote accepted
  • the lines

    \draw[spring] (m\i) -- (m\j) node[midway, above] (kuu\i) {$k$};
    \draw[spring] (m\i.east) -- (m\j.west) node[midway, above] (kuu\i) {$k^{quu}$};
    

gives the same result (except of nodes contents, which in second case is not defined).

  • instead

    \foreach \i in {0,...,6}{
       \pgfmathsetmacro{\j}{\i+1}
       \draw[spring] (m\i) -- (m\j) node[midway, above] (kuu\i) {$k$};
    

    you can write

    \foreach \i [count=\j from 1] in {0,...,6}{
         \draw[spring] (m\i.east) -- (m\j.west) node[midway, above] (kuu\i) {$k^{\uu}$};
    

    which because \uu is not defined, it doesn't work. replacing it with u gives

    \documentclass[tikz,border = 1mm]{standalone}
    \usetikzlibrary{patterns,shapes.geometric,decorations.pathmorphing}
    \def\bord{0.1cm}
    \def\radius{.2cm}
    \tikzset{
    spring/.style={thick,decorate,decoration={
    zigzag,
    segment length = 1mm,
    amplitude=0.7mm,
    pre length=1mm,
    post length=1mm}},
    mass/.style={circle,minimum width=2*\radius,anchor=center}
    }
    \begin{document}
    \begin{tikzpicture}[x=1cm,y=1cm,line join=round]
    % Bord gauche
    \fill [pattern = north east lines] (-.3,-2) rectangle (0,.5);
    \draw[thick] (0,-2) -- (0,.5);
    
    % Right edge
    \def\borddroit{8}
    \fill [fill=black!30!white] (\borddroit,-2) rectangle (\borddroit+.3,.5);
    \fill [pattern = north east lines] (\borddroit,-2) rectangle (\borddroit+.3,.5);
    \draw[ thick] (\borddroit,-2) -- (\borddroit,.5);
    
    % Masses
    \foreach \i in {1,2,...,6}{
        \node[mass,fill=blue] (m\i) at (\i,0) {};
    }
    \node[mass] (m0) at (0,0) {};
    \node[mass,fill=red] (m7) at (7,0) {};
    
    % Springs
    % Working plot
    \draw[spring] (m0.center) -- (m1.west);
    
    % Working \foreach without anchor
    \foreach \i [count=\j from 1] in {0,...,6}{
        \draw[spring] (m\i.east) -- (m\j.west) node[midway, above] (kuu\i) {$k^{u}$};
    }
    \end{tikzpicture}
    \end{document}
    

enter image description here

off-topic: above code (which only has corrected two lines in your code) can be written slightly shorter and more concise (with one \foreach loop):

\documentclass[tikz,border = 3mm]{standalone}
\usetikzlibrary{decorations.pathmorphing,
                patterns, positioning,
                quotes,
                shapes.geometric}
\def\radius{.2cm}
\begin{document}
\begin{tikzpicture}[
node distance = 5mm and 10mm,
  bord/.style = {rectangle, fill=#1, %inner sep=0pt,
                 pattern = north east lines,
                 minimum width=5mm, minimum height=25mm,
                 yshift=15mm,
                 node contents={}},
  mass/.style = {circle, minimum width=2*\radius, fill=#1},
spring/.style = {thick,decorate,decoration={zigzag,
                 segment length = 1mm,
                 amplitude=0.7mm,
                 pre length=1mm, post length=1mm}
                 },
                 ]
% Bord gauche
\coordinate (m0) at (\radius,0);
\node (m00) [bord=white, below left=5mm and 0mm of m0];
\draw[thick] (m00.north east) -- (m00.south east);

% Working \foreach without anchor
\foreach \i [count=\j from 1] in {0,...,6}
{
\ifnum\j<7
    \node[mass=blue] (m\j) at (\j,0) {};
\else
    \node[mass=red] (m\j) at (\j,0) {};
\fi
\draw[spring] (m\i) to ["$k^{u}$"] (m\j) ;
}
% Right edge
\node  (m8) [bord=gray!30, below right=of m7.center];
\draw[thick] (m8.north west) -- (m8.south west);
\end{tikzpicture}
\end{document}

result is:

enter image description here

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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