3

I am trying to the polygon in the left and I have produced the diagram on the right using the code below. I am asking for a solution to number the vertices which could be implemented for "any" regular a-sided polygon (I would like to only have to change the \pgfmathtruncatemacro\a{12} to get the desired result).

\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric, calc}

\begin{document}

  \begin{tikzpicture}[line cap=round]
        \def\r{80pt} %radius of circumscribed circle
        \pgfmathtruncatemacro\a{12} % number of polygon vertices
                

\foreach \i in {1, 2, ..., \a} {
    \coordinate (p\i) at ({-\r*cos(\i*(360/\a) + (90-360/\a)},{\r*sin(\i*(360/\a) + (90-360/\a))});
    \draw[fill=black] (p\i) circle (1pt);       
    \node[shift={(0,0)}] at (p\i) {\i};     
}

%Polygon Edges
\pgfmathtruncatemacro\b{\a-1} %used to iterate till \a-1
\foreach \i in {1, 2, ..., \b} {
    \pgfmathsetmacro{\j}{\i+1}
    \draw[thick,black] (p\i) -- (p\j);
}   
\draw[thick,black] (p\a) -- (p1);
            
  \end{tikzpicture}
\end{document}

3 Answers 3

3

You already have the solution in your code:

Just define a radius \def\rn{90pt}

Then, this: \node[shift={(0,0)}] at (p\i) {\i};

Becomes:

\node at (
   {-\rn*cos(\i*(360/\a) + (90-360/\a)},
   {+\rn*sin(\i*(360/\a) + (90-360/\a))}
){\i};
0
4

TikZ has polar coordinates: (<angle>:<radius>). (Technically, it allows for x and y radii.)

The numbers are labels with an explicit anchor since TikZ otherwise snaps the anchor to one of the eight compass directions. Since I'm using a circle shape for these labels, the proper anchor is okay and the node won't intersect the polygon.

The \tikzpolygon macro uses four arguments:

  1. optional arguments to the /tikz/polygon namespace to adjust one of the predefined styles for only that instance of the polygon,
  2. the phase, i.e. where the first vertex sits,
  3. the radius and
  4. the number of vertices – this must be an integer number and can't be a formula.

This draws the polygon always clockwise. In this configuration, it's not easy to change this direction. We'd need another argment that turns the - into a + in the formula for calculating the angle.


The graphs library with its extension graphs.standard which provides the subgraph C_n, it's actually much easier because you already have a key interface for radius, phase, number of vertices and direction – though, I haven't used it for the implementation of the \tikzpolygon macro. It takes the same arguments as before and sets the appropriate keys accordingly.

Only the proper placing of the label is just as much work as before.

Code (pure TikZ)

\documentclass[tikz]{standalone}
\tikzset{
  polygon/.cd,
  dot/.style={
    shape=circle, color=black, draw, fill, inner sep=+0pt, minimum size=+2pt},
  path/.style={draw},
  label/.style={shape=circle, inner sep=+.05em}}
\newcommand*\tikzpolygon[4][]{% #2 = phase, #3 = radius, #4 = number of vertices
  \tikz[line cap=round,polygon/.cd,#1]
  \path[polygon/path]
    foreach[
      count    = \j from 0,
      evaluate = \j as \angle using {#2-360/(#4)*\j}
    ] \i in {1,...,#4}{
      node[
        polygon/dot,
        label = {[polygon/label, anchor=\angle+180]\angle:$\i$}
      ] (pg-\i) at (\angle:{#3}) {}
    }
    plot[sharp cycle, samples at = {1,...,#4}] (pg-\x.center);%
}
\begin{document}
\tikzpolygon{90}{80pt}{12}
\tikzpolygon[path/.append style={fill=gray}]{180}{1cm}{17}
\end{document}

Output (pure Tikz)

enter image description here enter image description here

Code (graphs library)

\documentclass[tikz]{standalone}
\usetikzlibrary{graphs.standard}
\tikzset{
  polygon/.cd,
  dot/.style={
    shape=circle, color=black, fill, draw, inner sep=+0pt, minimum size=+2pt},
  path/.style={draw},
  label/.style={shape=circle, inner sep=+.05em}}
\newcommand*\tikzpolygon[4][]{% #2 = phase, #3 = radius, #4 = number of vertices
  \tikz[polygon/.cd,#1]
    \graph[
      edges     = {polygon/path},
      phase     = {#2},
      radius    = {#3},
      clockwise = {#4},
      n         = {#4},
      nodes={
        /tikz/polygon/dot, as=,
        /utils/exec=\pgfmathsetmacro\angle{#2-360/(#4)*(\tikzgraphnodename-1)},
        label/.expanded={[polygon/label, anchor=\angle+180]\angle:$\tikzgraphnodename$}},
    ]{subgraph C_n};%
}
\begin{document}
\tikzpolygon{90}{80pt}{12}
\tikzpolygon[path/.append style={green, thick}]{180}{1cm}{17}
\end{document}

Output (graphs library)

enter image description hereenter image description here

1
  • This is the loveliest part about TikZ for me. There is always a way to do a more modular version with a more complex code. all about that compromise.
    – anis
    Commented May 1, 2023 at 7:53
3

Modify a little bit your program like this:

% draw vertices and numbers
    \def\s{88pt}
    \foreach \i in {1, 2, ..., \a} {
        \coordinate (p\i) at ({-\r*cos(\i*(360/\a) + (90-360/\a)},{\r*sin(\i*(360/\a) + (90-360/\a))});
        \coordinate (q\i) at ({-\s*cos(\i*(360/\a) + (90-360/\a)},{\s*sin(\i*(360/\a) + (90-360/\a))});
        \draw[fill=black] (p\i) circle (1pt);       
        \node[shift={(0,0)}] at (q\i) {\i};     
    }

Output:

enter image description here

You must log in to answer this question.

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