10

The following image shows a recursive H-Layout tree.

H-Layout

It is called H-Layout because of its H unit consisting of 7 nodes.

My problem is:

How to draw such tree in a recursive manner instead of drawing each node explicitly?

  • 1
    See also tex.stackexchange.com/a/17823/86 – Loop Space Nov 15 '13 at 17:28
  • I rolled back the added tag because, as I understand it, tags are for questions. Since the question does not concern asymptote, it shouldn't have this tag even though it may be answered using this software. (I take it this is like questions tagged trees or tikz-trees, where I might answer with forest, but wouldn't add the forest tag unless the question concerned Forest somehow.) – cfr Apr 19 '18 at 23:48
17

Code A (preferred)

\documentclass[tikz]{standalone}
\tikzset{if/.code n args={3}{\pgfmathparse{#1}%
  \ifnum\pgfmathresult=1\pgfkeysalso{#2}\else\pgfkeysalso{#3}\fi}}
\begin{document}
\begin{tikzpicture}[nodes=draw, thick,
  H/.style n args={3}{% #1 = direction, #2=initial length, #3=levels
    if={0<=#3}{
      append after command={\pgfextra{\let\tikzLastnode\tikzlastnode}
        node[HH={#1}{#2}{#3}, shift=(#1+180:#2)] at (\tikzLastnode) {} edge (\tikzLastnode)
        node[HH={#1}{#2}{#3}, shift=(#1:#2)]     at (\tikzLastnode) {} edge (\tikzLastnode)}
    }{}},
  HH/.style n args={3}{
    append after command={\pgfextra{\let\tikzLastnode\tikzlastnode}
      node[H={#1}{#2/2}{#3-1}, shift=(#1+90:#2)] at (\tikzLastnode) {} edge (\tikzLastnode)
      node[H={#1}{#2/2}{#3-1}, shift=(#1-90:#2)] at (\tikzLastnode) {} edge (\tikzLastnode)
    }}]
\node[H={0}{3cm}{3}] {};
\end{tikzpicture}
\end{document}

Code B

\documentclass[tikz]{standalone}
\tikzset{if/.code n args={3}{\pgfmathparse{#1}%
  \ifnum\pgfmathresult=1\pgfkeysalso{#2}\else\pgfkeysalso{#3}\fi}}
\begin{document}
\begin{tikzpicture}[nodes=draw, thick, every pin edge/.style={}, every pin/.style={draw},
H/.style n args={3}{% #1 = direction, #2=initial length, #3=levels
  if={0<=#3}{% .6666em are 2*inner sep, \pgflinewidths are outer seps. Hard-coded values!
    pin={[pin distance=#2,
      pin={[pin distance=#2, H={#1}{(#2-.6666em-\pgflinewidth)/2}{#3-1}]#1+90:},
      pin={[pin distance=#2, H={#1}{(#2-.6666em-\pgflinewidth)/2}{#3-1}]#1-90:}]#1:},
    pin={[pin distance=#2,
      pin={[pin distance=#2, H={#1}{(#2-.6666em-\pgflinewidth)/2}{#3-1}]#1+90:},
      pin={[pin distance=#2, H={#1}{(#2-.6666em-\pgflinewidth)/2}{#3-1}]#1-90:}]#1+180:},
  }{}}]
\node[H={0}{3cm-.6666em-\pgflinewidth}{3}] {};
\end{tikzpicture}
\end{document}

Output

enter image description here

  • 2
    From a non-TikZ person: Can you explain why you prefer code A? Is it do to the hard-coded values? – Svend Tveskæg Nov 15 '13 at 7:59
  • wow! However, could you explain something more about your code, especially about the commands used and its recursive structure? – hengxin Nov 15 '13 at 8:35
12

enter image description here

A straightforward recursive Asymptote solution:

%
% htree.tex :
%
\documentclass[10pt,a4paper]{article}
\usepackage{lmodern}
\usepackage{subcaption}
\usepackage[inline]{asymptote}
\begin{asydef}
pen nodeBG=palered;
pen nodeBorder=deepblue+0.3bp;
pen linePen=nodeBorder;

guide H0=scale(1)*shift(-0.5,-0.5)*unitsquare;

void drawH0(pair o){
  filldraw(shift(o)*H0,nodeBG,nodeBorder);
}

void drawH(pair o,int n){
  real w=2.0^n;
  draw(shift(-w,0)*o--shift(w,0) *o,linePen);
  draw(shift(w,w)*o --shift(w,-w)*o,linePen);
  draw(shift(-w,w)*o--shift(-w,-w)*o,linePen);
  drawH0(o);
  drawH0(shift(-w,0)*o);
  drawH0(shift(w,0)*o);

  if(n>1) {
    drawH(shift(-w,w)*o,n-1);
    drawH(shift(-w,-w)*o,n-1);
    drawH(shift(w,w)*o,n-1);
    drawH(shift(w,-w)*o,n-1);
  }else{
    drawH0(shift(-w,w)*o);
    drawH0(shift(-w,-w)*o);
    drawH0(shift(w,w)*o);
    drawH0(shift(w,-w)*o);
  }
};

\end{asydef}
\usepackage[left=2cm,right=2cm,top=2cm,bottom=2cm]{geometry}
%
\begin{document}
%
\begin{figure}
\captionsetup[subfigure]{justification=centering}
    \centering
      \begin{subfigure}{0.49\textwidth}
\begin{asy}
size(10cm);
drawH((0,0),3);
H0=scale(0.5)*unitcircle;
nodeBG=blue;
nodeBorder=yellow+0.2bp;
linePen=red+0.5bp;
drawH((0,50),2);
\end{asy}
%
\caption{}
\label{fig:1a}
\end{subfigure}
%
\begin{subfigure}{0.49\textwidth}
\begin{asy}
size(10cm);
nodeBG=lightblue;
nodeBorder=orange+0.05bp;
linePen=olive+0.1bp;
drawH((0,0),5);
\end{asy}
%
\caption{}
\label{fig:1b}
\end{subfigure}
\caption{}
\label{fig:1}
\end{figure}
%
\end{document}
%
% Process :
%
% pdflatex htree.tex    
% asy htree-*.asy
% pdflatex htree.tex

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.