6

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}
9
  • 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
  • 2
    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
  • 1
    @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
11

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

output of above code

\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}

output of above snippet

Hence, in your example you might want to use

\n{line width}={scalar(\x{br}-\x{bl})*2.54/72.27},
4
  • 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

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.