0

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?

enter image description here

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}
2
  • 1
    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
1

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
   \global\advance\tikzcountchildi by1\relax%
   \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
   \global\advance\tikzcountchildii by1\relax%
   \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
   \global\advance\tikzcountchildiii by1\relax%
   \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
   \global\advance\tikzcountchildiv by1\relax%
   \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
    \global\advance\tikzcountchildv by1\relax%
   \fi
  \or
   \global\advance\tikzcountchildvi by1\relax%
   \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}

enter image description here

2
  • 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!
    – joba2ca
    Dec 15 '20 at 20:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.