# Drawing 3 hexagons on top of one another with additional lines

Is there a way to draw this figure so that it's not incredibly messy? I would like the two inner hexagons have their vertices lying exactly on the intersection points of some of the diagonals, just like I have drawn in the given picture. I know I may draw a hexagon with all its diagonals with

\begin{tikzpicture}[
dot/.style={circle,fill, inner sep=1.5pt, outer sep=0pt},
every label/.style={inner sep=0pt}]
\newdimen\R
\R=1.3cm
\draw[red]
(300:\R) \foreach \x in {360,60} {  -- (\x:\R) };
\foreach \i [count=\j] in {1,2,3,4,5,6}
{
\node (n\j) [dot, label=60*\j:$\i$] at (60*\j:\R) {};
}
\foreach \i in {1,...,6}
{
\ifnum\i=1
\foreach \j in {2,...,6}
\draw (n\i) -- (n\j);
\else
\foreach \j in {\i,...,6}
\draw (n\i) -- (n\j);
\fi
}
\end{tikzpicture}


But I am unsure of how to add the two hexagons inside this hexagon as I described (all regular hexagons by the way), plus the red lines from vertex $v$ in the hand-drawn picture as well. How would I go about doing this. The labels ${1,...,6}$ for the vertices is preferably not needed for this.

Another approach, slightly more compact could be the following:

\documentclass[border=2mm]{standalone}
\usepackage{ifthen}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}[line cap=round,line join=round]
\foreach\r in {1,2,4} \foreach[count=\i]\a in {0,60,...,300}
{% coordinates
\coordinate (\i-\r) at (\a:\r);
}
\foreach\r in {1,2,4} \foreach\i in {1,...,5}
{% gray lines
\pgfmathtruncatemacro\ii{\i+1}
\foreach\j in {\ii,...,6}
{%
\pgfmathtruncatemacro\d{\j-\i}
\ifthenelse{\NOT$$\d=3$$ \OR \r=4}
{% to avoid duplicating the diagonals
\draw[gray] (\i-\r) -- (\j-\r);
}{}
}
}
\foreach\i in {2,3,5,6}
{% red lines
\draw[red] (4-4) -- (\i-1);
}
\foreach\r in {1,2,4} \foreach\i in {1,...,6}
{% dots
\fill (\i-\r) circle (2pt);
}
% labels
\node at (4-4) [left] {$V_1$};
\node at (4-2) [left] {$V_2$}; % 2 is the hexagon radius, 4 for the fourth vertex starting east, anticlockwise
\end{tikzpicture}
\end{document}


EDIT: Added labels to some vertices.

• Thank you! Would there be a way of labelling the vertex from which the red lines are coming from as well as the vertex adjacent to it that is on the second hexagon? Commented Apr 22, 2021 at 0:56
• I made an edit. You only need to put a \node at the desired vertex. They are named (n-r) where r is the hexagon radius (1,2 or 4) and n is for counting, starting west, anticlockwise (as in the new code). Commented Apr 22, 2021 at 5:03

with contours

\documentclass[border=5pt]{standalone}

\usepackage{tikz}

\usepackage{contour}
\contournumber{32}

\begin{document}
\begin{tikzpicture}[
dot/.style={circle,fill, inner sep=1pt, outer sep=0pt},
every label/.style={inner sep=0pt,font=\tiny,}
]

\def\Ra{2cm}
\def\Rb{1cm}
\def\Rc{0.5cm}

\foreach \i [count=\j] in {1,...,6}
{
\node (na-\j) [dot, label=60*\j:\contour{white}{\i}] at (60*\j:\Ra) {};
}

\foreach \i in {1,...,6}
{
\ifnum\i=1
\foreach \j in {2,...,6}
\draw[gray] (na-\i) -- (na-\j);
\else
\foreach \j in {\i,...,6}
\draw[gray] (na-\i) -- (na-\j);
\fi
}

\foreach \i [count=\j] in {1,...,6}
{
\node (nb-\j) [dot, label=60*\j:\contour{white}{\i}] at (60*\j:\Rb) {};
}

\foreach \i in {1,...,6}
{
\ifnum\i=1
\foreach \j in {2,...,6}
\draw[gray] (nb-\i) -- (nb-\j);
\else
\foreach \j in {\i,...,6}
\draw[gray] (nb-\i) -- (nb-\j);
\fi
}

\foreach \i [count=\j] in {1,...,6}
{
\node (nc-\j) [dot, label=60*\j:\contour{white}{\i}] at (60*\j:\Rc) {};
}

\foreach \i in {1,...,6}
{
\ifnum\i=1
\foreach \j in {2,...,6}
\draw[gray] (nc-\i) -- (nc-\j);
\else
\foreach \j in {\i,...,6}
\draw[gray] (nc-\i) -- (nc-\j);
\fi
}

\foreach \i in {1,2,4,5} {
\draw[red] (na-3) -- (nc-\i);
}
\end{tikzpicture}
\end{document}


without labels

\documentclass[border=5pt]{standalone}

\usepackage{tikz}

\begin{document}
\begin{tikzpicture}[
dot/.style={circle,fill, inner sep=1pt, outer sep=0pt},
every label/.style={inner sep=0pt,font=\tiny,}
]

\def\Ra{2cm}
\def\Rb{1cm}
\def\Rc{0.5cm}

\foreach \i [count=\j] in {1,...,6}
{
\node (na-\j) [dot] at (60*\j:\Ra) {};
}

\foreach \i in {1,...,6}
{
\ifnum\i=1
\foreach \j in {2,...,6}
\draw[gray] (na-\i) -- (na-\j);
\else
\foreach \j in {\i,...,6}
\draw[gray] (na-\i) -- (na-\j);
\fi
}

\foreach \i [count=\j] in {1,...,6}
{
\node (nb-\j) [dot] at (60*\j:\Rb) {};
}

\foreach \i in {1,...,6}
{
\ifnum\i=1
\foreach \j in {2,...,6}
\draw[gray] (nb-\i) -- (nb-\j);
\else
\foreach \j in {\i,...,6}
\draw[gray] (nb-\i) -- (nb-\j);
\fi
}

\foreach \i [count=\j] in {1,...,6}
{
\node (nc-\j) [dot] at (60*\j:\Rc) {};
}

\foreach \i in {1,...,6}
{
\ifnum\i=1
\foreach \j in {2,...,6}
\draw[gray] (nc-\i) -- (nc-\j);
\else
\foreach \j in {\i,...,6}
\draw[gray] (nc-\i) -- (nc-\j);
\fi
}

\foreach \i in {1,2,4,5} {
\draw[red] (na-3) -- (nc-\i);
}
\end{tikzpicture}
\end{document}

• Is it possible to do this without the labels on the points? Commented Apr 21, 2021 at 8:13
• Just delete label=60*\j:$\i$ into your node commands. Commented Apr 21, 2021 at 8:20
• @causalityrefilm. I edited the answer Commented Apr 21, 2021 at 8:23

With a regular polygon shape, it's possible to use a more compact code:

\documentclass[tikz, border=2mm]{standalone}
\usetikzlibrary{shapes.geometric}

\begin{document}
\begin{tikzpicture}[
hexagon/.style={
regular polygon,
regular polygon sides=6,
draw,
minimum size=#1
}
]

\foreach \i/\dim in {a/6cm,b/3cm,c/1.5cm}{
\node[hexagon=\dim,clip] (\i) {};
\foreach \j/\list in {1/{3,4,5},2/{4,5,6},3/{5,6},4/{6}}{
\foreach \k in \list
\draw[thin, gray] (\i.corner \j)--(\i.corner \k);
}
\foreach \j in {1,2,...,6}
\fill ([shift={(60*\j+180:\pgflinewidth)}]\i.corner \j) circle (1pt);
}

\foreach \i in {1,2,4,5}
\draw[red] (a.corner 3)--(c.corner \i);

\node also [label=left:$v_1$, label=right:$v_2$] (a);

\end{tikzpicture}
\end{document}


Here are two solutions with the graphs libraries.

1. This is quite simple, this just draws three sets of hexagons on top of each other where every set is fully connected (→ K_n).

The edges that connect the nodes on the path of a hexagon are drawn black. Since this is a simple graph, these edges don't get drawn twice.

However, edges are still drawn on top of others. With an unfilled node, this wouldn't look good.

2. This solution makes sure that no edge is drawn on top of another one.

Only for the inner most hexagon all edges are drawn. For each node only the three edges to the next outer hexagon is added.

I took the liberty to change the style of the dots depending on the level (smaller and thinner).

## Code

\documentclass[tikz]{standalone}
\usetikzlibrary{graphs.standard, quotes, ext.misc}
\tikzset{
dots/.style={fill, draw, circle, inner sep=+.2em, thick},
graphs/every graph/.append style={
nodes=dots, empty nodes, edges=gray, simple,
\begin{document}
\begin{tikzpicture}
\foreach \i in {0, ..., 2}
{subgraph K_n, subgraph C_n[edges=black]};
\graph[use existing nodes]{
0 1, 0 4, 0 4["$v_2$" right],
0 1["$v_1$" left] --[red, very thick] {2 2, 2 3, 2 5, 2 6}
};
\end{tikzpicture}
\begin{tikzpicture}[
dots/.append style={fill=none, inner sep=+.2em/1.3^\i, line width=.6pt/1.3^\i}]
\newcommand*\maxIter{6}
\graph[simple, V={0,...,5}]{
\foreach[count=\j from -1] \i in {0, ..., \maxIter} {
/utils/TeX/ifnum={\i=\maxIter}{parse={subgraph K_n, subgraph C_n[edges=black]}}
{parse={subgraph C_n[edges=black]}}]},
{[/utils/TeX/ifnum={\i>0}{parse={
\foreach[evaluate={\p=int(Mod(\k-1,6)); % Previous and Next
\n=int(Mod(\k+1,6));}]\k in {0, ..., 5}{
\i\space\k -- {\j\space\p, \j\space\k, \j\space\n}}}}{}]}}};
\graph[use existing nodes]{
0 0, 0 3, 0 3["$v_2$" right],
0 0["$v_1$" left] --[red, very thick] {2 1, 2 2, 2 4, 2 5}
};
\end{tikzpicture}
\end{document}