13

In many \foreach iterative procedures in TikZ I would like to relate the generic node called n\x -- where x is a natural number -- to another node the name of which is obtained by applying basic mathemathical relationships to the number used in the name of the former.

Just to be clear, I wolud like to let's say draw a line from n\x to n\x+1 or to n\x*2 or to n\x-3, etc. So if x=4 I would like to draw lines like:

(n4)--(n5)
(n4)--(n8)
(n4)--(n1)

Is this possible?

In the following MWE I would like to draw lines between the nodes using an iterative procedure as previously mentioned.

\documentclass{article}
\usepackage{tikz}
%\usetikzlibrary{calc} <-- Would it be necessary?

\begin{document}

\begin{tikzpicture}
  \matrix[column sep=1cm]{
  \node (n1) {1}; & \node (n2) {2}; & \node (n3) {3}; & \node (n4) {4};\\
  };
  %\foreach \x in {1,...,3} <-- Something like this
  %\draw (n\x)--(n\x+1); 
\end{tikzpicture}

\end{document}

EDIT: This might be related, especially the comment at the end by @Mark Wibrow, but I can't get it to work.

5 Answers 5

13

Yes it is possible, you just need to compute \x+1 first. One way to do that is to use \pgfmathtruncatemacro:

enter image description here

Notes:

  • I added arrows to make it clear that there were three iterations.
  • As Paul Gaborit pointed out using \pgfmathsetmacro instead of \pgfmathtruncatemacro produces a real number so you get you get 3.0 instead of 3. So the arrow goes to n3.0 (anchor with angle 0 of node n3).

    enter image description here


You can also use the evaluate={\TempVar=int(\x+1) syntax:

Code: \pgfmathtruncatemacro

\documentclass{article}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
  \matrix[column sep=1cm]{
  \node (n1) {1}; & \node (n2) {2}; & \node (n3) {3}; & \node (n4) {4};\\
  };
  \foreach \x in {1,...,3} {%<-- Something like this
      \pgfmathtruncatemacro{\TempVar}{\x+1}
      \draw [red, -latex] (n\x)--(n\TempVar); 
  }%
\end{tikzpicture}

Code: evaluate

\documentclass{article}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
  \matrix[column sep=1cm]{
  \node (n1) {1}; & \node (n2) {2}; & \node (n3) {3}; & \node (n4) {4};\\
  };
  \foreach [evaluate={\TempVar=int(\x+1);}] \x in {1,...,3} {%<-- Something like this
      \draw [red, -latex] (n\x)--(n\TempVar); 
  }%
\end{tikzpicture}
15
  • 1
    +1 could you avoid \TempVar by using \pgfmathresult? Is there also an evaluate option of some kind?
    – cmhughes
    Commented Feb 13, 2014 at 19:01
  • ah, I see that @TorbjørnT. got the evaluate thing :)
    – cmhughes
    Commented Feb 13, 2014 at 19:01
  • @TorbjørnT.: Yep, was just in the process of adding that solution. But, not sure why the results are not the same. Commented Feb 13, 2014 at 19:02
  • 1
    @PierPaolo: It should be in the TikZ/pgf documentation: TikZ manual newest version online?. Commented Feb 13, 2014 at 20:56
  • 1
    @PeterGrill Section 56 of the TikZ/PGF deals with the syntax of \foreach and the evaluate option is discussed there, if I remember correctly :) I'm too lazy to check, tonight.
    – jub0bs
    Commented Feb 13, 2014 at 21:22
4

I think you just need expandable computations. Many things can be done with \numexpr.

\documentclass{article}
\usepackage{tikz}
\begin{document}\thispagestyle{empty}
\begin{tikzpicture}
  \matrix[column sep=1cm]{%
    \node (n11) {1}; & \node (n12) {2}; & \node (n13) {3}; & \node (n14) {4};\\
    \node (n21) {1}; & \node (n22) {2}; & \node (n23) {3}; & \node (n24) {4};\\
    \node (n31) {1}; & \node (n32) {2}; & \node (n33) {3}; & \node (n34) {4};\\
    };
  \foreach \x in {1,...,3} {%<-- Something like this
      \draw [red, -latex]
      (n\x\x)--(n\x\the\numexpr\x+1\relax);  
  }%
\end{tikzpicture}
\end{document}

nodes

2

Another version of evaluate:

\documentclass{article}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
  \matrix[column sep=1cm]{
  \node (n1) {1}; & \node (n2) {2}; & \node (n3) {3}; & \node (n4) {4};\\
  };
  \foreach \x [remember=\x as \lastx (initially 1)] in {2,...,4}{
    \draw [red, -latex] (n\lastx)--(n\x);
  }%
\end{tikzpicture}
\end{document}

enter image description here

2

It's possible to avoid the matrix

 \documentclass{article}
 \usepackage{tikz}

 \begin{document}
 \begin{tikzpicture}
  \node (n1) {1};
   \foreach \x in {2,...,4} {%
     \node (n\x) at (\x-1,0) {\x};
     \draw[red, -latex] (n\the\numexpr\x-1) -- (n\x);    
   }
 \end{tikzpicture}
 \end{document}

enter image description here

1

As nobody mentioned the use of let, I add this answer for the seek for completeness.

\begin{tikzpicture}
  \matrix[column sep=1cm]{
  \node (n1) {1}; & \node (n2) {2}; & \node (n3) {3}; & \node (n4) {4};\\
  };
  \foreach \a in {1,...,3} {%<-- Something like this (but don't use \x inside let!)
      \draw[red, -latex] let \n{a}={int(\a+1)} in (n\a)--(n\n{a});
  }%
\end{tikzpicture}

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .