# Regular polygon: edges between vertices of odd index

I want to draw a regular polygon in which there is an edge between the consecutive vertices of odd index: For instance with 8 vertices, I want a path 1 -- 3 -- 5 -- 7 -- 1. To do this with a large number of vertices, I'd like to do this automatically rather than to handwrite the full path.

Using some answers here (in particular this one), I've come up with the following solution (here with 16 vertices):

\documentclass[tikz]{standalone}

\usetikzlibrary{shapes.geometric,calc}

\begin{document}
\begin{tikzpicture}
\node (pol) [minimum size=\textwidth,regular polygon, rotate=90,regular polygon sides=8] at (0,0) {};
\foreach \n in {1, 2, ..., 8} {
\node[anchor=\n*(360/8)] at (pol.corner \n) {\n};
}
\foreach \n [remember=\n as \lastn (initially 7)] in {1, 3, ...,  7} {
\path[draw] (pol.corner \lastn) -- (pol.corner \n);
}
\end{tikzpicture}
\end{document}


The problem is that I get the path 3 -- 5 -- 7 -- 1 plus the edge 3 -- 7 instead of the path I wanted. It seems to me (I may well be wrong!) that \lastn is not correctly updated at the beginning of the loop.

Do you see what is going wrong? Do you have a different way to achieve the same goal?

• Should \lastn be initialized to 7 instead of 8? If I do that, I get exactly the shape that you describe at the beginning... path from 1--3--5--7--1 – darthbith Feb 9 '15 at 19:24
• Of course, this was a mistake! Yet, I still get the exact same path as I described, once the mistake corrected. I do not get the same shape as you seem to get! This reinforces my impression that \lastn is not correctly initialized in the \foreach loop. – Bruno Feb 9 '15 at 20:02

As you can see here, there's no problem with your code and TiKZ 3.0

\documentclass[tikz]{standalone}

\usetikzlibrary{shapes.geometric,calc}

\begin{document}
\begin{tikzpicture}
\node (pol) [draw=red,minimum size=\textwidth,regular polygon, rotate=90,regular polygon sides=8] at (0,0) {};
\foreach \n in {1, 2, ..., 8} {
\node[anchor=\n*(360/8)] at (pol.corner \n) {\n};
}
\foreach \n [remember=\n as \lastn (initially 7)] in {1, 3, ...,  7} {
\path[draw] (pol.corner \lastn) -- (pol.corner \n);
}

\begin{scope}[yshift=13cm]
\node (pol) [draw=red,minimum size=\textwidth,regular polygon, rotate=90,regular polygon sides=18] at (0,0) {};
\foreach \n in {1, 2, ..., 18} {
\node[anchor=\n*(360/18)] at (pol.corner \n) {\n};
}
\foreach \n [remember=\n as \lastn (initially 17)] in {1, 3, ...,  17} {
\path[draw] (pol.corner \lastn) -- (pol.corner \n);
}
\end{scope}
\end{tikzpicture}
\end{document}


Maybe an alternative for even-number-of-size polygons (odd is also possible but a little more tedious)?

\documentclass[tikz]{standalone}
\usetikzlibrary{shapes.geometric}
\begin{document}
\begin{tikzpicture}
\def\mycorner{18}
\node (pol) [minimum size=\textwidth,regular polygon,
rotate=90,regular polygon sides=\mycorner] at (0,0) {};
\foreach \n in {1, 2, ..., \mycorner} {
\node[anchor=\n*(360/\mycorner)] at (pol.corner \n) {\n};
}
\foreach \n [evaluate={\modn = int(Mod(\n+2,\mycorner));}] in {1,3,...,\mycorner} {
\path[draw] (pol.corner \n) -- (pol.corner \modn);
}
\end{tikzpicture}
\end{document}


• Thanks for this nice solution! I'll accept your answer if nobody catches the problem in my solution... – Bruno Feb 9 '15 at 20:03
• @Bruno I suspect that you are using TikZ 2.10 and the problem will go away if you instead use {1,3,5,7} in your foreach loop. That was a known problem. Now it's v3.00 and it is solved. Alternatively you can try removing (initially 7) part and use \def\lastn{7} outside your loop manually. – percusse Feb 10 '15 at 11:04

Done with MetaPost, inserted in a LuaLaTeX program. In the following code the odd_subpolygon takes care of all the job, with two parameters to be adjusted at will: the number n of sides of the main regular polygon and its radius r (in centimeters). As examples, the following code applies this macro thrice, respectively with n=6, n=8 and n=16.

\documentclass{article}
\usepackage{luamplib}
\mplibsetformat{metafun}
\mplibtextextlabel{enable}
\everymplib{verbatimtex \leavevmode etex;
% Macro producing a unit regular polygon
vardef unit_regpoly(expr n) =
save angl; angl := 360/n; right for i = 1 upto n-1: -- dir(i*angl) endfor -- cycle
enddef;
% Macro drawing a n-sided regular polygon of radius r and its subpolygon
vardef odd_subpolygon(expr n, r) =
clearxy; save polygon; path polygon;
polygon = unit_regpoly(n) scaled r; draw polygon withcolor red;
% polygon and labels
for i = 1 upto n:
z[i] = point i-1 of polygon; freelabel(decimal i, z[i], origin);
endfor;
% Subpolygon
draw z1 for i = 3 step 2 until n: -- z[i] endfor -- cycle;
enddef;
r = 2cm; % radius parameter
beginfig(0);}
\everyendmplib{endfig;}
\begin{document} % Three examples, with n = 5, 8 and 16 respectively
\begin{center}
\begin{mplibcode} odd_subpolygon(6, r); \end{mplibcode}
\begin{mplibcode} odd_subpolygon(8, r); \end{mplibcode}
\par\bigskip
\begin{mplibcode} odd_subpolygon(16, r); \end{mplibcode}
\end{center}
\end{document}


A PSTricks solution using the pst-poly package:

\documentclass{article}

\usepackage{multido}
\usepackage{pst-poly}
\usepackage{xfp}

\newcommand*\hori[2]{\fpeval{#1+#2+0.05}}
\newcommand*\verti[2]{\fpeval{#1+#2+0.1}}

\def\polygon[#1]#2#3{%
\begin{pspicture}(-\hori{#1}{#2},-\verti{#1}{#2})(\hori{#1}{#2},\verti{#1}{#2})
\rput(0,0){\PstPolygon[unit = #2, PolyNbSides = #3]}
\rput(0,0){\PstPolygon[unit = #2, PolyNbSides = \fpeval{2*#3}, linecolor = red]}
\multido{\i = 1+1}{\fpeval{2*#3}}{%
\rput(\fpeval{(#1+#2)*cos(pi/#3*(\i-1))},\fpeval{(#1+#2)*sin(pi/#3*(\i-1))}){$\i$}}
\end{pspicture}}

\begin{document}

\polygon[0.25]{2}{8}

\end{document}


The figure is drawn using the general marco

\polygon[distance between outer polygon and numbers]