我需要绘制一个关联多面体,即一个五边形,其顶点用平面二叉树装饰,边用平面非二叉树装饰。我正在使用蒂克兹带有标签森林以下是我的尝试:
\begin{center}
\begin{tikzpicture}
\node[circle,draw, scale = 0.7] (A)
{\begin{forest}
for tree = {grow'=90,circle, fill, minimum width = 4pt, inner sep = 0pt, s sep = 13pt, l sep = 1ex}
[
[ [[ {},tier = top][]] [{},tier = top] ] [{}, tier = top]
]
\end{forest}};
\node[circle,draw, scale = 0.7] (B) [above right = of A] {\begin{forest}
for tree = {grow'=90,circle, fill, minimum width = 4pt, inner sep = 0pt, s sep = 13pt, l sep = 1ex}
[
[ [][] ] [ [] [] ]
]
\end{forest}};
\node[circle,draw, scale = 0.7] (C) [right = of B] {\begin{forest}
for tree = {grow'=90,circle, fill, minimum width = 4pt, inner sep = 0pt, s sep = 13pt, l sep = 1ex}
[
[{},tier = top ] [ [{},tier = top] [ [] [{},tier = top] ] ]
]
\end{forest}};
\node[circle,draw, scale = 0.7] (D) [below right = of A] {\begin{forest}
for tree = {grow'=90,circle, fill, minimum width = 4pt, inner sep = 0pt, s sep = 13pt, l sep = 1ex}
[
[[{},tier = top] [[{},tier = top][]] ] [{},tier = top]
]
\end{forest}};
\node[circle,draw, scale = 0.7] (E) [right = of D] {\begin{forest}
for tree = {grow'=90,circle, fill, minimum width = 4pt, inner sep = 0pt, s sep = 13pt, l sep = 1ex}
[
[{},tier = top] [ [[{},tier = top][{},tier = top]] [{},tier = top] ]
]
\end{forest}};
\draw[thin] (A) --node[above left,circle,draw, scale = 0.5]{\begin{forest}
for tree = {grow'=90,circle, fill, minimum width = 4pt, inner sep = 0pt, s sep = 13pt, l sep = 1ex}
[
[[{},tier = top] []]
[{},tier = top]
[{},tier = top]
]
\end{forest}} (B) --node[above,circle,draw, scale = 0.5]{\begin{forest}
for tree = {grow'=90,circle, fill, minimum width = 4pt, inner sep = 0pt, s sep = 13pt, l sep = 1ex}
[
[{},tier = top]
[{},tier = top]
[[{},tier = top] []]
]
\end{forest}} (C) -- node[right,circle,draw, scale = 0.5]{\begin{forest}
for tree = {grow'=90,circle, fill, minimum width = 4pt, inner sep = 0pt, s sep = 13pt, l sep = 1ex}
[
[{},tier = top]
[ [{},tier = top] [] [] ]
]
\end{forest}} (E) --node[below,circle,draw, scale = 0.5]{\begin{forest}
for tree = {grow'=90,circle, fill, minimum width = 4pt, inner sep = 0pt, s sep = 13pt, l sep = 1ex}
[
[{},tier = top]
[ [{},tier = top] [] ]
[{},tier = top]
]
\end{forest}} (D) -- node[below left,circle,draw, scale = 0.5]{\begin{forest}
for tree = {grow'=90,circle, fill, minimum width = 4pt, inner sep = 0pt, s sep = 13pt, l sep = 1ex}
[
[[{},tier = top] [] [] ]
[{},tier = top]
]
\end{forest}}(A);
\end{tikzpicture}
\end{center}
正如您所见,得到的五边形在几个方面很不好看:
- 它不是一个正五边形(我以一种简单的方式将节点 AD 相互定位)。
- 顶点节点处的圆大小不同,因为包围的标签树大小不同。
- 顶点节点不知道它们之间有边节点,因此顶点节点的圆和边节点的圆有时会相交。
我怎样才能使这个装饰过的五边形不那么难看呢?
答案1
我的答案结合了另外两个答案,“画一个正六边形”和“绘制树状符号”。
对于正多边形,使用极坐标(angle:radius)
。对于五边形,角度差为 360/5=72 度。当度数开始在水平 x 轴上计算时,我添加了 36 度来稍微旋转它。在下面的 TeX 代码中,我将计算结果保留为显式,例如2*72+36
对于第三个节点。
对于树状符号,请参阅其他答案中的文档。除了基本命令 L、I、R、l、i、r 之外,我还添加了一些用于更陡峭边缘的命令(M、N、S、T、m、n、s、t)。我不知道树木应该是什么样子,但很容易改变点的大小,也可以在交叉点添加点。
最后说明:TikZ 在嵌套图片时很挑剔。当用树标记边缘时,这一点变得很明显:一旦开始用明确的移位微调位置,树中的点就会开始改变其位置。因此,我使用savebox
es 来“冻结”树,然后使用框作为标签。
\documentclass[border=2mm,tikz]{standalone}
\usetikzlibrary{automata}
% See https://tex.stackexchange.com/a/364842 for the documentation
\makeatletter
\newcommand\RSloop{\@ifnextchar\bgroup\RSloopa\RSloopb}
\makeatother
\newcommand\RSloopa[1]{\bgroup\RSloop#1\relax\egroup\RSloop}
\newcommand\RSloopb[1]%
{\ifx\relax#1%
\else
\ifcsname RS:#1\endcsname
\csname RS:#1\endcsname
\else
\GenericError{(RS)}{RS Error: operator #1 undefined}{}{}%
\fi
\expandafter\RSloop
\fi
}
\newcommand\X{0}
\newcommand\RS[1]%
{\begin{tikzpicture}
[every node/.style=
{circle,draw,fill,minimum size=1.5pt,inner sep=0pt,outer sep=0pt},
line cap=round
]
\coordinate(\X) at (0,0);
\RSloop{#1}\relax
\end{tikzpicture}
}
\newcommand\RSdef[1]{\expandafter\def\csname RS:#1\endcsname}
\newlength\RSu
\RSu=1ex
\RSdef{i}{\draw (\X) -- +(90:\RSu) node{};}
\RSdef{l}{\draw (\X) -- +(135:\RSu) node{};}
\RSdef{m}{\draw (\X) -- +(120:\RSu) node{};}
\RSdef{n}{\draw (\X) -- +(105:\RSu) node{};}
\RSdef{r}{\draw (\X) -- +(45:\RSu) node{};}
\RSdef{s}{\draw (\X) -- +(60:\RSu) node{};}
\RSdef{t}{\draw (\X) -- +(75:\RSu) node{};}
\RSdef{I}{\draw (\X) -- +(90:\RSu) coordinate(\X I);\edef\X{\X I}}
\RSdef{L}{\draw (\X) -- +(135:\RSu) coordinate(\X L);\edef\X{\X L}}
\RSdef{M}{\draw (\X) -- +(120:\RSu) coordinate(\X L);\edef\X{\X L}}
\RSdef{N}{\draw (\X) -- +(105:\RSu) coordinate(\X L);\edef\X{\X L}}
\RSdef{R}{\draw (\X) -- +(45:\RSu) coordinate(\X R);\edef\X{\X R}}
\RSdef{S}{\draw (\X) -- +(60:\RSu) coordinate(\X R);\edef\X{\X R}}
\RSdef{T}{\draw (\X) -- +(75:\RSu) coordinate(\X R);\edef\X{\X R}}
\newsavebox\sba\savebox\sba[5mm][l]{\RS{{Mm}{Ii}{R{ir}}}}
\newsavebox\sbb\savebox\sbb[5mm][l]{\RS{{Ss}{Ii}{L{il}}}}
\newsavebox\sbc\savebox\sbc[5mm][l]{\RS{{L{lir}}{Rr}}}
\newsavebox\sbd\savebox\sbd[5mm][l]{\RS{{Ll}{Ilr}{Rr}}}
\newsavebox\sbe\savebox\sbe[5mm][l]{\RS{{Ll}{R{lir}}}}
\begin{document}
\begin{tikzpicture}[
vertex/.style={circle,draw,minimum size=8mm,inner sep=0pt},
edge/.style={circle,draw,minimum size=6mm,inner sep=0pt}
]
\newcommand\R{2cm}
\node[vertex](v0) at (0*72+36:\R) {\RS{{MMm}{S{Mm}S{ms}}}};
\node[vertex](v1) at (1*72+36:\R) {\RS{{L{li}}{R{ir}}}};
\node[vertex](v2) at (2*72+36:\R) {\RS{{SSs}{M{Ss}M{sm}}}};
\node[vertex](v3) at (3*72+36:\R) {\RS{{L{Ll}{R{lr}}}{RRr}}};
\node[vertex](v4) at (4*72+36:\R) {\RS{{R{Rr}{L{rl}}}{LLl}}};
\draw (v0) edge node[edge,above=1pt,xshift=2pt]{\usebox\sba} (v1);
\draw (v1) edge node[edge,left,yshift=4pt]{\usebox\sbb} (v2);
\draw (v2) -- node[edge,left,yshift=-4pt]{\usebox\sbc} (v3);
\draw (v3) -- node[edge,below=1pt,xshift=2pt]{\usebox\sbd} (v4);
\draw (v4) -- node[edge,right=1pt]{\usebox\sbe} (v0);
\end{tikzpicture}
\end{document}