如何使用 Tikz 绘制递归 H-Layout 树?

如何使用 Tikz 绘制递归 H-Layout 树?

下图显示了递归的 H-Layout 树。

H 布局

由于其H单元由7个节点组成,因此称为H-Layout。

我的问题是:

如何绘制这样的树递归方式而不是明确地绘制每个节点?

答案1

代码 A(首选)

\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}

代码 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}

输出

在此处输入图片描述

答案2

在此处输入图片描述

一个简单的递归Asymptote解决方案:

%
% 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

相关内容