3

The following code is a simple double foreach statement that generates a staircase of coordinates.

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\begin{document}

\begin{tikzpicture} \foreach \i in {0,...,10} { \pgfmathsetmacro{\r}{10-\i} \foreach \j in {0,...,\r} { \node at (\i,\j) {$(\i,\j)$}; } } \end{tikzpicture} \end{document}

I wanted to simplify by not setting a macro and directly putting 10-\i in the second foreach statement's range indicator. However, none of my attempts worked and threw a variety of errors.

Attempt 1:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\begin{document}

\begin{tikzpicture} \foreach \i in {0,...,10} { \foreach \j in {0,...,10-\i} { \node at (\i,\j) {$(\i,\j)$}; } } \end{tikzpicture} \end{document}

Error Message:

! Illegal unit of measure (pt inserted).

Attempt 2:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\begin{document}

\begin{tikzpicture} \foreach \i in {0,...,10} { \foreach \j in {0,...,(10-\i)} { \node at (\i,\j) {$(\i,\j)$}; } } \end{tikzpicture} \end{document}

Error Message:

! Missing number, treated as zero.

Attempt 3:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\begin{document}

\begin{tikzpicture} \foreach \i in {0,...,10} { \foreach \j in {0,...,{10-\i}} { \node at (\i,\j) {$(\i,\j)$}; } } \end{tikzpicture} \end{document}

Error Message:

! Illegal unit of measure (pt inserted).

Attempt 4:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\begin{document}

\begin{tikzpicture} \foreach \i in {0,...,10} { \foreach \j in {0,...,\pgfmathparse{10-\i}\pgfmathresult} { \node at (\i,\j) {$(\i,\j)$}; } } \end{tikzpicture} \end{document}

Error Message:

! Incomplete \iffalse; all text was ignored after line 11.

Is it impossible to do this task in this way?

  • Not really supported, stick to the setmacro method. See linked questions in https://tex.stackexchange.com/questions/251195/using-dynamic-bounds-in-a-tikz-foreach?noredirect=1&lq=1#comment598704_251195 – user202729 Oct 10 '22 at 17:45

3 Answers3

3

The option [parse=true] does this job.

enter image description here

See more details in Section 88 Repeating Things: The Foreach Statement of PGF/TikZ manual.

enter image description here

\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\foreach \i[parse=true] in {0,...,10}
\foreach \j in {0,...,10-\i} 
\path (\i,\j) node{$(\i,\j)$};
\end{tikzpicture}
\end{document}

My personal comment: TikZ's foreach is quite flexible; however, TikZ/TeX is a typesetting system with limited computation, so it is far from natural syntax in comparison with some strong programming languages, such as Python, Asymptote. For instance, the following Asymptote code is very natural. (also note that the Asymptote code can be embbed into .tex document)

enter image description here

// Asymptote has a handy "for" loop
// Run on http://asymptote.ualberta.ca/
size(12cm);
for (int i=0; i<10; ++i)
for (int j=0; j<10-i; ++j)
label("$($"+string(i)+","+string(j)+"$)$",(i,j),blue); 
Black Mild
  • 17,569
3

There is also the evaluate option for \foreach that has the same effect.

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\begin{document}

\begin{tikzpicture} \foreach \i[evaluate=\i as \r using 10-\i] in {0,...,10} { \foreach \j in {0,...,\r} { \node at (\i,\j) {$(\i,\j)$}; } } \end{tikzpicture} \end{document}

Sandy G
  • 42,558
2

You can directly put \the\numexpr10-\i\relax in the \foreach and TikZ will expand it (note however that the computations possible in \numexpr are very limited, basically only +, -, *, /, and parentheses).

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\begin{document}

\begin{tikzpicture} \foreach \i in {0,...,10} { \foreach \j in {0,...,\the\numexpr10-\i\relax} { \node at (\i,\j) {$(\i,\j)$}; } } \end{tikzpicture} \end{document}

Skillmon
  • 60,462