11

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?

2
  • 3
    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
    Commented Feb 9, 2015 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
    Commented Feb 9, 2015 at 20:02

4 Answers 4

10

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}

enter image description here

11

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}

enter image description here

2
  • Thanks for this nice solution! I'll accept your answer if nobody catches the problem in my solution...
    – Bruno
    Commented Feb 9, 2015 at 20:03
  • 2
    @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
    Commented Feb 10, 2015 at 11:04
6

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}
  \qquad
  \begin{mplibcode} odd_subpolygon(8, r); \end{mplibcode}
  \par\bigskip
  \begin{mplibcode} odd_subpolygon(16, r); \end{mplibcode}
\end{center}
\end{document}

enter image description here

1

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}

output

The figure is drawn using the general marco

\polygon[distance between outer polygon and numbers]
        {<radius of the circumcircle>}
        {<number of sides of the inner polygon>}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .