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}
2
  • 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 :) May 25 '17 at 18:38
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.

6
  • No I don't mind, and am very pleased with this solution. But it seems to me the second pgfextra is superflouous. May 25 '17 at 18:46
  • @ChristophFrings Might indeed be. To be honest didn't test it extensively.
    – percusse
    May 25 '17 at 18:46
  • Then I'll just keep the first one :) Thx for your inhumanly fast and pertinent answers. May 25 '17 at 18:50
  • @ChristophFrings The pleasure is mine
    – percusse
    May 25 '17 at 19:30
  • @percusse It looks strange to me this \pgfextra{--}, why you need it ? And when you draw it (something that you don't do, I know ;)) you can see that rounded corners=25pt are not applied to all corners.
    – Kpym
    May 26 '17 at 15:28
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 :(

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.