# \foreach within \draw doesn't seem to work

I'm desperately trying to make this work

\documentclass{minimal}
\usepackage{tikz}

\newcommand\polygon[3][]{
\pgfmathsetmacro{\angle}{360/#2}
\pgfmathsetmacro{\startangle}{0}
\begin{scope}[#1]
\draw \foreach\i in {1,...,#2}{
\pgfmathsetmacro{\x}{cos(\startangle + \angle*\i)*#3}
\pgfmathsetmacro{\y}{sin(\startangle + \angle*\i)*#3}
\ifnum\i=1 \else--\fi ({\x},{\y})
};
\end{scope}
}

\begin{document}
\begin{tikzpicture}
\polygon{5}{1}
\end{tikzpicture}
\end{document}


I scraped all around the internet trying to get tips from other people's problems that could help me make this work, but I still get this error

Package tikz Error: Giving up on this path. Did you forget a semicolon?.


What point am I missing? I have no prior experience with TikZ.

UPDATE: after making several trials I just realized my problem is somehow related to the two \pgfmathsetmacro inside the loop. Any tips on how to get this working?

• This is unrelated to your problem, but please take a look at Why should the minimal class be avoided?. I prefer using the standalone class for graphics MWEs. – Paul Gessler Apr 18 '15 at 20:49
• @PaulGessler oh, I get it. Indeed, this doc was a test one I made for purposes of seeing how TikZ works, however I can't even make this thing work. – Mauren Apr 18 '15 at 20:51
• You know there's a library with a shape for drawing regular polygons, right? I assume the issue here is that you want one side to be open. – cfr Apr 18 '15 at 21:06
• @cfr I wasn't aware of that. However I need a little more than a regular polygon, that's why I was trying to make my own command. – Mauren Apr 18 '15 at 21:08
• @Mauren You could use the regular polygon shape without any options and then you can at least reference its anchors (.corner 1, .corner 2, ...) without the need for any calculations. — Also, look up polar coordinates. There is no need to do your own trigonometric calculations. (Hint: The syntax is (<angle>:<radius>).) — I would be interest in your goal. Maybe there are different, or even easier, ways, to do this. – Qrrbrbirlbel Apr 18 '15 at 21:58

Did you want something like this?

\documentclass[tikz,border=5pt]{standalone}
\newcommand\polygon[3][]{
\pgfmathsetmacro{\angle}{360/#2}
\pgfmathsetmacro{\startangle}{0}
\begin{scope}[#1]
\draw \foreach\i in {1,...,#2}{
\ifnum\i=1 \else--\fi ({cos(\startangle + \angle*\i)*#3},{sin(\startangle + \angle*\i)*#3})
};
\end{scope}
}

\begin{document}
\begin{tikzpicture}
\polygon{5}{1}
\end{tikzpicture}
\end{document}


I don't think you can use things like \pgfsetmacro in the middle of a path, but you can just put the calculations into the specification of the coordinates.

This produces an open pentagon:

Don't use minimal for examples, by the way.

# EDIT

Note that you could also use a pic. I don't know exactly what you want to put in the scope specification, but you can pass some things using pic actions as follows:

\documentclass[tikz,border=5pt]{standalone}
\tikzset{
pics/open polygon/.style n args=2{
code={
\pgfmathsetmacro{\angle}{360/#1}
\pgfmathsetmacro{\startangle}{0}
\draw [pic actions] \foreach\i in {1,...,#1}{
\ifnum\i=1 \else--\fi ({cos(\startangle + \angle*\i)*#2},{sin(\startangle + \angle*\i)*#2})
};
}
},
}

\begin{document}
\begin{tikzpicture}
\pic [draw=cyan!50!blue, outer color=cyan!50!blue, inner color=cyan!15] {open polygon={5}{1}};
\end{tikzpicture}
\end{document}


• @Mauren You're welcome. You might want to think about using a pic instead of a command. (See edited answer for an example.) – cfr Apr 18 '15 at 21:18
• You can use arbitrary code in a TikZ path with \pgfextra or the /utils/exec key. You can also use \foreach's evaluate. In this case, putting the calculation inside the coordinate specification is just as right (you use them only once, so why bother). – Qrrbrbirlbel Apr 18 '15 at 21:36
• @Qrrbrbirlbel Thanks. I just figured this would work and couldn't see any reason to mess around looking up the alternatives, to be honest. (Why define macros when you aren't going to reuse the code at all?) – cfr Apr 18 '15 at 21:50

The problem comes from a calculation macro inside of the \draw path. So, I suggest separating the calculation from drawing by first performing the calculations and storing the results in \coordinates labeled a-1, a-2, ..., a-n, then drawing the path with the aid of these coordinates. Here is how you can do this:

\documentclass{standalone}
\usepackage{tikz}

\newcommand\polygon[3][]{
\pgfmathsetmacro{\angle}{360/#2}
\pgfmathsetmacro{\startangle}{0}
\begin{scope}[#1]
\foreach\i in {1,...,#2}{
\pgfmathsetmacro{\x}{cos(\startangle + \angle*\i)*#3}
\pgfmathsetmacro{\y}{sin(\startangle + \angle*\i)*#3}
\coordinate (a-\i) at ({\x},{\y});
}
\draw\foreach \i in{1,...,#2}{\ifnum\i=1 \else --\fi (a-\i)};
\end{scope}
}
\begin{document}
\begin{tikzpicture}
\polygon{5}{1}
\end{tikzpicture}
\end{document}


• Yes. But the OP said this. – cfr Apr 18 '15 at 21:51
• @cfr Umm! yes, just saw this. But I think some of the audience may not be aware of this alternative. Should I delete it? – AboAmmar Apr 18 '15 at 21:58
• Perhaps edit it to make clear that it doesn't address exactly the OP's situation? The thing is, you have to fix and compile the code to have a clue why the OP might not be able to use this solution. So, in one sense the question isn't clear. In another... I really don't know. It is useful information in general - it just can't be used here. (And I don't even know if the reason I assumed it wouldn't work is really the OP's reason or not.) I'd suggest editing and just explain that it won't, of course, work if you want to draw only n-1 sides of the polygon as seems to be the case here. – cfr Apr 18 '15 at 22:01
• (+1) Though that's an entirely different answer which does address the question! – cfr Apr 18 '15 at 23:50