# Let-Defined Limits for \foreach Loop with TikZ

I'd like to compute the upper and lower limits of a TikZ \foreach loop using the let statement. Unfortunately, this throws errors when I try code along the following lines:

\draw
let \n{lo}={<computation>},
\n{hi}={<computation>}
in
\foreach \var in {\n{lo},...,\n{hi}} { <STUFF> }


I can easily define a tail-recursive macro that does what I want but ideally I'd like to use TikZ's \foreach statement. Interestingly, the \n{lo} isn't causing problems (in my case) but the \n{hi} is...

Any pointers to a solution appreciated.

Here's a minimal-ish example:

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}

\begin{tikzpicture}
\draw
let \p{bl}=(0,0),
\p{br}=(1,0),
% THIS COMPUTATION IS RELATED TO THE PROBLEM
% \n{line width}={1} % WORKS FINE
\n{line width}={\x{br}-\x{bl}},
\n{x height}={1.2},
\n{line density}={2},
\n{x heights}={\n{line width}/\n{x height}},
\n{aid lines}={ceil(\n{line density} * \n{x heights})},
\n{aid line factor}={\n{x height} / \n{line density}},
\n{first}={-10},
\n{last}={\n{aid lines}-\n{first}}
in
% DOESN'T WORK
\foreach \cpcnt in {\n{first},...,\n{last}} {%
(\p{bl}) -- + (\cpcnt * \n{aid line factor},0)
};%
\end{tikzpicture}

\end{document}

• works for me. Depends on what you have in <STUFF> – percusse Dec 21 '17 at 18:25
• A minimal non working example is needed, in my simple test I have no problem. – egreg Dec 21 '17 at 18:26
• @percusse Yes. Sometimes it doesn't work and sometimes it does. Clearly (IMHO) it's a bug in TikZ. I have a complex example but it wouldn't help if I posted it. I'll see if I can isolate the problem but I'm afraid it won't help... – Marc van Dongen Dec 21 '17 at 18:28
• The result of \n{.} macros are with dimensions (because you would use them in drawings), in your case it is 58pt. So when it is used in foreach it becomes {-10.0,...,58pt} and trips up. So it is not a bug. – percusse Dec 21 '17 at 19:09
• @percusse Thanks. Much appreciated. Will have a look at that. Still odd, the \n{} sometimes works and sometimes doesn't. Thanks again. – Marc van Dongen Dec 21 '17 at 19:21

You can see the difference between the working and the non-working versions from

\begin{tikzpicture}
\draw
let \p{bl}=(0,0),
\p{br}=(1,0),
\n{a}={1},
\n{b}={\x{br}-\x{bl}}
in
node {$a=\n{a}$, $b=\n{b}$};
\end{tikzpicture}


which outputs

\n macros can be dimensionless number or a dimension, cf. the manual page 160 (for version 3.0.1a, in section 14.15 The Let Operation). \n{b} becomes a dimension because \x has a dimension.

You can strip the dimension with the scalar function, but you might need scale it afterward:

\begin{tikzpicture}
\draw
let \p{bl}=(0,0),
\p{br}=(1,0),
\n{a}={1},
\n{b}={scalar(\x{br}-\x{bl})},
\n{c}={scalar(\x{br}-\x{bl})*2.54/72.27} % scale from points to cm
in
node {$a=\n{a}$, $b=\n{b}$, $c=\n{c}$};
\end{tikzpicture}


Hence, in your example you might want to use

\n{line width}={scalar(\x{br}-\x{bl})*2.54/72.27},

• Thanks. The last time I read the TikZ manual was a few years ago. I cannot recall anything about values with and without units. The scalar function is what I'm looking for. Thanks a lot. – Marc van Dongen Dec 22 '17 at 6:38
• @MarcvanDongen I had the wrong page reference by the way, should have been 160 not 560. – Torbjørn T. Dec 22 '17 at 7:53
• No problem. I found it. I'll also try to send you something I should have sent earlier this year! – Marc van Dongen Dec 22 '17 at 12:18
• @MarcvanDongen Oh, don't worry about that, it's not a big deal. – Torbjørn T. Dec 22 '17 at 12:30