6

Programmatically constructing a closed path with tikz is easy:

\path (a0) \foreach \i in {1, ..., 7} {-- (a\i)} -- cycle;

But it forces to single out the first point. Reversing the construction pattern is rejected by tikz:

\path \foreach \i in {0, ..., 7} {(a\i) --} cycle;

and I suppose there are good reasons for that (I read an explanation about that on SE, but have lost reference to that answer edit found it here).

Unfortunately, if the building pattern is more complex than just adding point after point, the working solution can be quite tedious :

\path \foreach \i in {0, ..., 8} {(a\i) -- (\i*10:3) -- (b\i) --} cycle;

would be quite compact a way, but to get it to work I would need to code:

\path (a0) -- (0:3) -- (b0) \foreach \i in {0, ..., 8} {-- (a\i) -- (\i*10:3) -- (b\i)} -- cycle;

And that isn't even a complicated computation.

Is there some magic that would allow me to build the entire path using only \foreach ?

EDIT: example of such a construction

\documentclass{standalone}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
    \fill[gray, rounded corners=25pt, even odd rule] (30:5) -- (120:3) -- (0:4) \foreach \i in {1, ...,19} {-- (30+18*\i:5) -- (120+18*\i:3) -- (18*\i:4)} -- cycle;
\end{tikzpicture}
\end{document}
  • please provide small complete document (MWE) that we not need to write code from scratch ... – Zarko May 25 '17 at 18:19
  • @Zarko I've added an example, though I need to stress that I am not looking for an ad-hoc solution for a given problem. I hope it is aesthetically pleasing :) – Christoph Frings May 25 '17 at 18:38

2 Answers2

3

If you don't mind adding some if's you can place the missing -- here and there

\begin{tikzpicture}
 \fill[gray, rounded corners=25pt, even odd rule]  \foreach \i in {0,...,19} {
  \pgfextra{\ifnum\i=0\relax\else--\fi}
  (30+18*\i:5) -- (120+18*\i:3) -- (18*\i:4) 
  \pgfextra{\ifnum\i=0\relax--\fi}
} -- cycle;
\end{tikzpicture}

Actually you can shorten those further but the gist is the same.

percusse
  • 157,807
2

What you should know is that foreach body is executed in a group {...}. So this makes everything tricky. To avoid this problems you can use another loop like \xintFor from xinttools library, for example. Or you can do it in a tricky way :

\documentclass[border=7mm]{standalone}
\usepackage{tikz}
\begin{document}
  \def\segment{(30:5) -- (120:3) -- (0:4)}
  \begin{tikzpicture}
   \fill[gray, rounded corners=25pt, even odd rule]
     \segment foreach \i in {0,...,20} {[rotate=\i*18] -- \segment} -- cycle;
  \end{tikzpicture}
\end{document}

enter image description here

Note: If you want to draw it you can start from 1, but if you want to fill it with even odd rule, it looks like you have to start from 0 and draw the first segment twice. But in this case there is some small problem in the beginning :(

Kpym
  • 23,002