下图显示了递归的 H-Layout 树。
由于其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