# Grow circular tree with forest

## Issue

I have this circular grown tree in tikz. Because this graphic will become quite complex, I want to switch to forest. I found the grow-option in forest, but I cannot get it to do what I want.

If forest is not the right package for this, I would of course use a solution in regular tikz as well.

## Target Output

The node shapes are secondary for now. What I would like - in contrast to the graphic below - is that the nodes are evenly distributed around the center/root; basically the nodes should be evenly distributed on several "orbits" around the center, but still be connected to the respective parent. The graphic below does not distribute the nodes equally around the center, but around the parent.

Bonus: Also, I would like to use a loop for node creation, so that I can vary the number of created nodes easily. Is that possible?

## Source (if needed)

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{trees, shapes}

\begin{document}
\pagestyle{empty}

\tikzstyle{level 1}=[sibling angle=90, shape = rectangle, minimum size=1.5em]
\tikzstyle{level 2}=[sibling angle=45, shape = rectangle, minimum size=1em]
\tikzstyle{level 3}=[sibling angle=22.5, shape = rectangle, minimum size=0.5em]
\tikzstyle{every node}=[fill]
\tikzstyle{edge from parent}=[draw, very thin]

\begin{tikzpicture}[
grow cyclic,
shape = circle,
level distance=3em,
triangle/.style = {fill=blue!20, regular polygon, regular polygon sides=3 },
border rotated/.style = {shape border rotate=180}
]
\node[triangle, border rotated, minimum size=3em] {} child [color=\A] foreach \A in {black, black, black, black}
{ node {} child [color=\B] foreach \B in {black, black, black}
{ node {} child [color=\C] foreach \C in {black, black, black}
{ node {} }
}
};
\end{tikzpicture}

\end{document}

• I do not know if forest can do this. However, tex.stackexchange.com/q/532650 seems to be remotely related.
– user230864
Dec 13 '20 at 20:52
• Forest cannot do this in any reasonable way. Like herding cats, even if it is not totally impossible, it is not something you want to spend some of your life attempting.
– cfr
Dec 25 '20 at 1:45

I really just copied the code just from https://tex.stackexchange.com/a/539395, and probably by shear luck it works. While I do not fully understand what's going on, a few things that I think are true:

1. Contrary to a comment above, mindmap is not needed. All one needs is to modify the so-called growth function.
2. You need to compile several times to have the final result, it seems that you need to add a compilation for every level.

Code:

\documentclass[tikz,border=9]{standalone}
\usetikzlibrary{trees,decorations,shapes.geometric}
\makeatletter
\newcount\tikzcountchildi
\newcount\tikzcountchildii
\newcount\tikzcountchildiii
\newcount\tikzcountchildiv
\newcount\tikzcountchildv
\newcount\tikzcountchildvi
\tikzset{garlic growth/.style={growth function=\tikz@grow@garlic,
/tikz/mmap/name=#1,mmap/#1/.is family,
mmap/initialize counts,
execute at end scope={%
\tikz@mmap@store@aux{n-i}{\the\tikzcountchildi}%
\tikz@mmap@store@aux{n-ii}{\the\tikzcountchildii}%
\tikz@mmap@store@aux{n-iii}{\the\tikzcountchildiii}%
\tikz@mmap@store@aux{n-iv}{\the\tikzcountchildiv}%
\tikz@mmap@store@aux{n-v}{\the\tikzcountchildv}%
\tikz@mmap@store@aux{n-vi}{\the\tikzcountchildvi}}},
mmap/.cd,initialize counts/.code={\tikzcountchildi=0%
\tikzcountchildii=0%
\tikzcountchildiii=0%
\tikzcountchildiv=0%
\tikzcountchildv=0%
\tikzcountchildvi=0%
}
}
\def\tikz@mmap@store@aux#1#2{%
\immediate\write\@mainaux{\string\expandafter\xdef\noexpand\csname pgfk@/tikz/mmap/\pgfkeysvalueof{/tikz/mmap/name}/#1\string\endcsname{#2}}}%
\def\tikz@mmap@get@from@aux#1#2{%
\ifcsname pgfk@/tikz/mmap/\pgfkeysvalueof{/tikz/mmap/name}/#1\endcsname
\edef#2{\csname pgfk@/tikz/mmap/\pgfkeysvalueof{/tikz/mmap/name}/#1\endcsname}%
\else
\edef#2{0}%
\fi
}

\newcount\tikzcountgrandchild
\def\tikz@grow@garlic{%
\pgfmathsetmacro{\pgfutil@tempa}{\pgfkeysvalueof{/tikz/mmap/overall rotation}}%
\ifcase\tikztreelevel
\or
\tikz@mmap@get@from@aux{n-i}{\myni}%
\tikz@mmap@get@from@aux{n-ii}{\mynii}%
\tikz@mmap@get@from@aux{n-1-\the\tikzcountchildi}{\mynall}%
\tikz@mmap@get@from@aux{p-1-\the\tikzcountchildi}{\mypi}%
\ifnum\mynii>0
\pgfmathsetmacro{\pgfutil@tempa}{\pgfutil@tempa+\pgfkeysvalueof{/tikz/mmap/sign}%
*(\pgfkeysvalueof{/tikz/mmap/child weight}*(\mypi)*360/\mynii+%
(1-\pgfkeysvalueof{/tikz/mmap/child weight})*(\tikzcountchildi-1)*360/\myni)}%
\fi
\or
\tikz@mmap@get@from@aux{n-ii}{\mynii}%
\tikz@mmap@get@from@aux{n-1-1}{\mynall}%
\ifnum\mynii>0
\pgfmathsetmacro{\pgfutil@tempa}{\pgfutil@tempa+\pgfkeysvalueof{/tikz/mmap/sign}%
*(\tikzcountchildii-1-\mynall/2)*360/\mynii}%
\fi
\ifnum\tikznumberofcurrentchild=1\relax
\tikz@mmap@store@aux{n-1-\the\tikzcountchildi}{\the\tikznumberofchildren}%
\tikz@mmap@store@aux{p-1-\the\tikzcountchildi}{\the\numexpr\tikzcountchildii-1}%
\tikz@mmap@store@aux{a-1-\the\tikzcountchildi-\the\tikzcountchildii}{\pgfutil@tempa}%
\fi
\or
\ifnum\tikznumberofcurrentchild=1\relax
\tikz@mmap@store@aux{n-1-\the\tikzcountchildi-\the\tikzcountchildii}{\the\tikznumberofchildren}%
\tikz@mmap@store@aux{p-1-\the\tikzcountchildi-\the\tikzcountchildii}{\the\numexpr\tikzcountchildiii-1}%
\fi
\tikz@mmap@get@from@aux{n-iii}{\myniii}%
\tikz@mmap@get@from@aux{a-1-1-1}{\bettera}%
\tikz@mmap@get@from@aux{n-1-1-1}{\mynall}%
\ifdim\bettera pt=0pt\relax
\else
\pgfmathsetmacro{\pgfutil@tempa}{\bettera}%
\fi
\ifnum\myniii>0
\pgfmathsetmacro{\pgfutil@tempa}{\pgfutil@tempa+\pgfkeysvalueof{/tikz/mmap/sign}%
*(\tikzcountchildiii-1-\mynall/2)*360/\myniii}%
\fi
\or
\tikz@mmap@get@from@aux{n-iv}{\myniv}%
\ifnum\myniv>0
\pgfmathsetmacro{\pgfutil@tempa}{\pgfutil@tempa+\pgfkeysvalueof{/tikz/mmap/sign}*(\tikzcountchildiv-1)*360/\myniv}%
\fi
\or
\tikz@mmap@get@from@aux{n-v}{\mynv}%
\pgfmathsetmacro{\pgfutil@tempa}{\pgfutil@tempa+\pgfkeysvalueof{/tikz/mmap/sign}*(\tikzcountchildv-1)*360/\mynv}%
\ifnum\mynv>0
\fi
\or
\tikz@mmap@get@from@aux{n-vi}{\mynvi}%
\ifnum\myvi>0
\pgfmathsetmacro{\pgfutil@tempa}{\pgfutil@tempa+(\tikzcountchildvi-1)*360/\mynvi}%
\fi
\fi
\pgftransformreset%
\pgftransformshift{\pgfpoint{\pgfkeysvalueof{/tikz/mmap/overall xshift}}%
{\pgfkeysvalueof{/tikz/mmap/overall yshift}}}%
\pgftransformrotate{\pgfutil@tempa}%
\pgftransformxshift{\the\tikzleveldistance}%
}
\makeatother
\begin{document}
\tikzset{mmap/.cd,
name/.initial=undef,
overall rotation/.initial=0,
overall xshift/.initial=0pt,
overall yshift/.initial=0pt,
sign/.initial=1,
child weight/.initial=0.5,
/tikz/.cd,
Xshift/.style={xshift=#1,mmap/overall xshift=#1},
Yshift/.style={yshift=#1,mmap/overall yshift=#1},
branch color/.style={
concept color=#1!80,ball color=#1!50,
every child/.append style={concept color=#1!50},
}
}

\begin{tikzpicture}[garlic growth=A,mmap/child weight=0,
mmap/overall rotation=15,mmap/sign=-1,
shape = circle,
level 1/.style={shape = rectangle, minimum size=1.5em,
level distance=1.2cm,
},
level 2/.style={shape = rectangle, minimum size=1em,
level distance=2.4cm,
},
level 3/.style={shape = rectangle, minimum size=0.5em,
level distance=3.6cm,sibling angle=40,
},
edge from parent/.style={draw, very thin},nodes=fill,
level distance=3em,
triangle/.style = {fill=blue!20, regular polygon, regular polygon sides=3 },
border rotated/.style = {shape border rotate=180}
]
\node[triangle, border rotated, minimum size=3em] {} child [color=\A] foreach \A in {black, black, black, black}
{ node {} child [color=\B] foreach \B in {black, black, black}
{ node {} child [color=\C] foreach \C in {black, black, black}
{ node {} }
}
};
\end{tikzpicture}
\end{document}


• In case the OP wants to see how it renders with a mindmap. here
– JeT
Dec 13 '20 at 23:33
• I have to say I did not expect such a monstrosity of a tex file. But it works as intended, so thank you very much! Dec 15 '20 at 20:42