我想使用包 forest 绘制一个二叉树,并简化树的一部分,绘制一个三角形。我还想在这个三角形上放置一个标签,并且标签应该包含在三角形中。
这是我的消息来源:
\begin{forest}
for tree={l+=0.5cm, s sep+=1cm}
[$q_5$ [$q_8$ [$q_1$ [$\overline q_2$] [$\overline q_6$]]
[$q_9$ [$q_3$ [$\vdots$] [$\vdots$]] [$q_5$ [$\vdots$, tria] [$\vdots$]] ] ]
[$q_3$ [$\overline q_2$] [$q_4$ [$\overline q_2$] [$\overline q_6$]] ]
]
\end{forest}
例如我想用三角形替换节点 $\vdots$ 并在其上放置标签。
你能帮助我吗?
(我认为这个包有一个很好的语法来绘制树,自动定位也很棒。所以我的第二个问题是,我在哪里可以找到一些好的森林包模板/教程?我不明白风格命令有效..)
答案1
新答案
如果您拥有相对较新的 Forest 和/或 Ti 版本,请使用此版本钾Z. 使用时描述的冲突triangle
不再适用,因为
- Forest 不再定义
triangle
,其任何库也不再定义; shapes.geometric
不再定义triangle
。
因此,尝试使用triangle
根本行不通,但这并不是因为有两个相互竞争的定义。现在的问题是根本没有定义。但是,您可以使用isosceles triangle
来定义一个新triangle
选项。
tria
我还更新了多边形情况的定义,并尝试triangle
在有兄弟节点的情况下使其工作得更合理。在这种情况下,不再需要插入空节点,因为它们会自动插入。
triangle
[左] 和tria
[右]的当前结果:
代码:
\documentclass[border=5pt]{standalone}
\usepackage{forest}
\usetikzlibrary{shapes.geometric}
\begin{document}
\forestset{
tria/.style={
node format={
\noexpand\node [
draw,
shape=regular polygon,
regular polygon sides=3,
inner sep=0pt,
outer sep=0pt,
\forestoption{node options},
anchor=\forestoption{anchor}
]
(\forestoption{name}) {\foresteoption{content format}};
},
child anchor=parent,
},
triangle/.style={
isosceles triangle, isosceles triangle apex angle=45, child anchor=parent, shape border uses incircle, shape border rotate=90, draw,
delay={
if={
>O_> {!u.n children}{1}
}{
replace by/.process={ Ow {id} {[, coordinate, tier=##1, append, l'=0pt]}},
for siblings={tier/.option=id},
no edge,
}{},
},
},
}%
\begin{forest}
for tree={l'+=0.5cm, s sep'+=1cm, math content}
[q_5 [q_8 [q_1 [\overline q_2] [\overline q_6]]
[q_9 [q_3 [\vdots] [\vdots]] [q_5 [\vdots, triangle] [\vdots]] ] ]
[q_3 [\overline q_2] [q_4 [\overline q_2] [\overline q_6]] ]
]
\end{forest}
\begin{forest}
for tree={l'+=0.5cm, s sep'+=1cm, math content}
[q_5 [q_8 [q_1 [\overline q_2] [\overline q_6]]
[q_9 [q_3 [\vdots] [\vdots]] [q_5 [\vdots, tria] [\vdots]] ] ]
[q_3 [\overline q_2] [q_4 [\overline q_2] [\overline q_6]] ]
]
\end{forest}
\end{document}
原始答案
如果您拥有旧版本的 Forest 和 Ti,请使用此版本钾Z 并且由于某种原因,您无法更新。
通常,您可以通过将形状的名称作为选项传递给节点来指定形状。例如,这适用于ellipse
手册第 27 页所示的情况:
\documentclass[tikz, border=5pt]{standalone}
\usepackage{forest}
\begin{document}
\pgfkeys{/forest,
tria/.append style={ellipse, draw},
}
\begin{forest}
for tree={l+=0.5cm, s sep+=1cm}
[$q_5$ [$q_8$ [$q_1$ [$\overline q_2$] [$\overline q_6$]]
[$q_9$ [$q_3$ [$\vdots$] [$\vdots$]] [$q_5$ [$\vdots$, tria] [$\vdots$]] ] ]
[$q_3$ [$\overline q_2$] [$q_4$ [$\overline q_2$] [$\overline q_6$]] ]
]
\end{forest}
\end{document}
但是,triangle
被特别解释为forest
指定从父级到子级的三角形边缘路径:
我想到了两种三角形节点形状的可能性。第一种与 Ignasi 的解决方案相同:使用库shapes.geometric
。不过,我的版本将边绘制到三角形的顶点,而不是边的中间。第二种是使用forest
带有空节点的三角形边。
可能性 1
\documentclass[tikz, border=5pt]{standalone}
\usetikzlibrary{shapes.geometric}
\usepackage{forest}
\begin{document}
\pgfkeys{/forest,
tria/.style={
node format={
\noexpand\node [
draw,
shape=regular polygon,
regular polygon sides=3,
inner sep=0pt,
outer sep=0pt,
\forestoption{node options},
anchor=\forestoption{anchor}
]
(\forestoption{name}) {\foresteoption{content format}};
},
child anchor=north,
edge path={
\noexpand\path[\forestoption{edge}]
(!u.parent anchor) --
(.child anchor)\forestoption{edge label};
},
},
}
\begin{forest}
for tree={l+=0.5cm, s sep+=1cm}
[$q_5$ [$q_8$ [$q_1$ [$\overline q_2$] [$\overline q_6$]]
[$q_9$ [$q_3$ [$\vdots$] [$\vdots$]] [$q_5$ [$\vdots$, tria] [$\vdots$]] ] ]
[$q_3$ [$\overline q_2$] [$q_4$ [$\overline q_2$] [$\overline q_6$]] ]
]
\end{forest}
\end{document}
可能性 2
\documentclass[tikz, border=5pt]{standalone}
\usetikzlibrary{shapes.geometric}
\usepackage{forest}
\begin{document}
\begin{forest}
for tree={l+=0.5cm, s sep+=1cm}
[$q_5$ [$q_8$ [$q_1$ [$\overline q_2$] [$\overline q_6$]]
[$q_9$ [$q_3$ [$\vdots$] [$\vdots$]] [$q_5$ [, [, label={$\vdots$}, triangle]] [$\vdots$]] ] ]
[$q_3$ [$\overline q_2$] [$q_4$ [$\overline q_2$] [$\overline q_6$]] ]
]
\end{forest}
\end{document}
请注意,第二种解决方案与兄弟节点配合使用效果不佳 - 因此使用了两个空节点。但是,在我看来,它确实看起来更简洁一些。另一方面,我不确定它在实践中的效果如何,而多边形解决方案应该相对有弹性。
答案2
受到 cfr 答案的启发,我现在使用以下内容(圆圈表示普通节点,三角形表示概念子树):
\documentclass{article}
\usepackage{tikz, forest}
\usetikzlibrary{shapes.geometric}
\forestset{%
default preamble={
for tree={
circle,
draw,
inner sep=0pt,
minimum size=.5cm,
font=\scriptsize,
edge=->,
anchor=north
}
},
ssarbre/.style={isosceles triangle,
draw,
shape border rotate=90,
minimum size=.7cm,
child anchor=apex,
anchor=apex}
}
\begin{document}
\begin{forest}
[$x$ [$y$ [$A$,ssarbre] [$z$ [$B$,ssarbre] [$C$,ssarbre] ] ] [$D$,ssarbre] ]
\end{forest}
\end{document}
并得到