Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[pgf] math in foreach?

1,164 views
Skip to first unread message

Sven Köhler

unread,
Aug 13, 2010, 8:09:18 AM8/13/10
to
Hi,

I'm trying to build a simple loop, somewhat like this:

\foreach \x in {#3+1,#3+2, ...,#4}

Here's an even simpler example:

\foreach \x in {1+1,2+1,...,10}

Unfortunatly, this doesn't work. Neither #3+1, 1+1 nor any other
arithmetik expression in evaluated by \foreach.

Any idea, how I can make this work?
I already tried adding brackets and braces:
(#3+1), {#3+1} or (1+1), {1+1}
No improvement.

Actually, it's possible to use arithmetic expressions all over the place
in tikz. But the \foreach statement doesn't seem to handle arithmetic
expressions, or I'm trying the wrong way.


Regards,
Sven

Marc van Dongen

unread,
Aug 13, 2010, 9:09:07 AM8/13/10
to
On Aug 13, 1:09 pm, Sven Köhler <remove-sven.koeh...@gmail.com> wrote:

> I'm trying to build a simple loop, somewhat like this:
>         \foreach \x in {#3+1,#3+2, ...,#4}

The first two members of the set suggest that you want to use
``pattern matching'' on
the pattern ``#3+'' but the last member in the list doesn't have seem
to have this pattern
in it (but this may depend on the actual value of #4). For example,
I'd imagine that
\foreach \in in {#3+1,#3+2,...,#3+4} _would_ work (untested) and
should
assign #3+1, #3+2, #3+3, and #3+4 to \x. You were probably hoping that
tikz would
evaluate the expression with the +, but the notation you used is for
pattern matching.

> Actually, it's possible to use arithmetic expressions all over the place
> in tikz. But the \foreach statement doesn't seem to handle arithmetic
> expressions, or I'm trying the wrong way.

Yes, I think you're trying the wrong way (but I'm not 100% sure). The
tikz manual
explains the various kinds of allowed expressions. Some examples may
also be
found on on Page 95 in http://csweb.ucc.ie/~dongen/LaTeX-and-Friends.pdf
(this is
mainly based on the tikz manual).

Regards,


Marc van Dongen

Sven Köhler

unread,
Aug 13, 2010, 9:52:02 AM8/13/10
to
Hi,

Am 13.08.2010 15:09, schrieb Marc van Dongen:
> On Aug 13, 1:09 pm, Sven Köhler <remove-sven.koeh...@gmail.com> wrote:
>
>> I'm trying to build a simple loop, somewhat like this:
>> \foreach \x in {#3+1,#3+2, ...,#4}
>
> The first two members of the set suggest that you want to use
> ``pattern matching'' on
> the pattern ``#3+'' but the last member in the list doesn't have seem
> to have this pattern
> in it (but this may depend on the actual value of #4). For example,
> I'd imagine that
> \foreach \in in {#3+1,#3+2,...,#3+4} _would_ work (untested) and
> should
> assign #3+1, #3+2, #3+3, and #3+4 to \x. You were probably hoping that
> tikz would
> evaluate the expression with the +, but the notation you used is for
> pattern matching.

Thanks for you thoughts on this one!

I know that \foreach can also be used like

\foreach \x/\y in {1/2, 3/4}

but the "..." in my \foreach are actually not indicating that I left
something out. They are the standard notation for numeric foreach loops,
like in

\foreach \x in {1,2,...,10}


I want to do a forach loop, that loops from the numeric value of #3+1 to
the numeric value of #4 in steps of 1.

Can you think of any way of how to do this?

>> Actually, it's possible to use arithmetic expressions all over the place
>> in tikz. But the \foreach statement doesn't seem to handle arithmetic
>> expressions, or I'm trying the wrong way.
>
> Yes, I think you're trying the wrong way (but I'm not 100% sure). The
> tikz manual
> explains the various kinds of allowed expressions. Some examples may
> also be
> found on on Page 95 in http://csweb.ucc.ie/~dongen/LaTeX-and-Friends.pdf
> (this is
> mainly based on the tikz manual).

I read the very few pages about \foreach. And the only examples were
like this:

\foreach \x in {1,2,...,10}


But there was no hint, on how to replace the bounds (1 and 10) by more
complex expressions.


Regards,
Sven

Marc van Dongen

unread,
Aug 13, 2010, 10:52:59 AM8/13/10
to
On Aug 13, 2:52 pm, Sven Köhler <remove-sven.koeh...@gmail.com> wrote:

> I want to do a forach loop, that loops from the numeric value of #3+1 to
> the numeric value of #4 in steps of 1.

[snip]

> But there was no hint, on how to replace the bounds (1 and 10) by more
> complex expressions.
>
> Regards,
>   Sven

The following is a minimal example that shows how you may do this.

\documentclass{minimal}

\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}

\begin{tikzpicture}
\draw let \n{a}=1,
\n{b}={1+2} in
(0,0) \foreach \x in {\n{a},\n{b},...,10} { -- (\x,0) node
{\x}};
\end{tikzpicture}

\end{document}

Regards,


Marc van Dongen

Sven Köhler

unread,
Aug 13, 2010, 11:45:33 AM8/13/10
to

At first sight, this looked like a nice solution. Unfortunately, my
current \foreach looks like this:

\foreach \x in {1, 2, ..., 10} {
\path ...;
\draw ...;
}

As it seems, I have to convert the contents of the foreach to something,
that can be part of single \path or \draw command, which is rather
unfortunate.

Is there a way to use the let operation for a whole block of \path and
\draw commands?


Furthermore, in your example above \n{a} expands to "1.0" rather than
simply 1. Similarly \n{b} expands to "3.0" instead of "3".
Funny enough, the whole sequence is 1.0, 3.0, 5, 7, 9 - so the ".0" is
omitted from the last number, but the first two have it.

The proposed solution is not very satisfactory yet.


Regards,
Sven

Marc van Dongen

unread,
Aug 13, 2010, 3:18:50 PM8/13/10
to
On Aug 13, 4:45 pm, Sven Köhler <remove-sven.koeh...@gmail.com> wrote:
> Am 13.08.2010 16:52, schrieb Marc van Dongen:

[ snip ]

> At first sight, this looked like a nice solution. Unfortunately, my

You're welcome.

> current \foreach looks like this:
>
> \foreach \x in {1, 2, ..., 10} {
>         \path ...;
>         \draw ...;
>
> }
>

[ snip ]

> Is there a way to use the let operation for a whole block of \path and
> \draw commands?

That depends on what you want. Your initial question was about the
values that were generated. It was not about the body of the \foreach.
Please let us know exactly what you need, so no ... in \path or \draw.
A minimal example please.

> Furthermore, in your example above \n{a} expands to "1.0" rather than
> simply 1. Similarly \n{b} expands to "3.0" instead of "3".
> Funny enough, the whole sequence is 1.0, 3.0, 5, 7, 9 - so the ".0" is
> omitted from the last number, but the first two have it.
>
> The proposed solution is not very satisfactory yet.

Well, stating you needed integers would have helped....

Regards,


Marc van Dongen

Marc van Dongen

unread,
Aug 15, 2010, 2:04:04 AM8/15/10
to

\documentclass{minimal}

\usepackage{tikz}

\newcounter{first}
\newcounter{second}
\newcounter{last}
\setcounter{first}{1}
\setcounter{second}{\thefirst}
\addtocounter{second}{1}
\setcounter{last}{10}

\begin{document}
\begin{tikzpicture}
\foreach \x in {\thefirst,\thesecond,...,\thelast} {
\path (\x,0) coordinate (X);
\draw (X) node[below] {\x} -- +(0,1);
};
\end{tikzpicture}
\end{document}

Sven Köhler

unread,
Aug 18, 2010, 7:15:24 AM8/18/10
to
Am 13.08.2010 21:18, schrieb Marc van Dongen:
> That depends on what you want. Your initial question was about the
> values that were generated. It was not about the body of the \foreach.
> Please let us know exactly what you need, so no ... in \path or \draw.
> A minimal example please.

Well, here's a more precise specification:

Given: two parameters, #3 and #4, can be assumed to be integer
Wanted:
A foreach loop from (#3+1) to #4, such that the loop variable always
expands to an integer. The body of the foreach loop is to contain \draw
and/or \path commands.

>> Furthermore, in your example above \n{a} expands to "1.0" rather than
>> simply 1. Similarly \n{b} expands to "3.0" instead of "3".
>> Funny enough, the whole sequence is 1.0, 3.0, 5, 7, 9 - so the ".0" is
>> omitted from the last number, but the first two have it.
>>
>> The proposed solution is not very satisfactory yet.
>
> Well, stating you needed integers would have helped....

I had no idea that this would run into that issue. Strange things are
happening here. Funny enough, the result isn't "5.0" but "5" in your
example.

Well, I'll try to give better specifications next time.

Thanks for all your answers, BTW.


Regards,
Sven

Sven Köhler

unread,
Aug 18, 2010, 7:18:34 AM8/18/10
to
Am 15.08.2010 08:04, schrieb Marc van Dongen:
> \documentclass{minimal}
>
> \usepackage{tikz}
>
> \newcounter{first}
> \newcounter{second}
> \newcounter{last}
> \setcounter{first}{1}
> \setcounter{second}{\thefirst}
> \addtocounter{second}{1}
> \setcounter{last}{10}
>
> \begin{document}
> \begin{tikzpicture}
> \foreach \x in {\thefirst,\thesecond,...,\thelast} {
> \path (\x,0) coordinate (X);
> \draw (X) node[below] {\x} -- +(0,1);
> };
> \end{tikzpicture}
> \end{document}

Thanks. I will use counters.


Regards,
Sven

0 new messages