
State tree structure (STS)
s — это особый вид диаграмм, принадлежащий к state chart
семейству s.
Типичный пример STS
можно изобразить следующим образом:
Количество ветвей, государственных меток и символов креста или союза может быть сформировано в любую произвольную структуру по замыслу дизайнера.
Возможно, tikz-trees
это будет приближение, но, как я проверил, я не думаю, что он способен сгенерировать что-то похожее на эту цифру в целом.
Есть ли какая-нибудь специализированная библиотека для чего-то подобного TikZ
?!
решение1
Вот версия, которая определяет стиль Forest, state tree
для форматирования деревьев этого типа. Предположения, основанные на примере, таковы:
- дети должны быть распределены равномерно;
- первый и последний дочерний элемент должны находиться на одинаковом расстоянии от родителя;
- ребра следует рисовать только для первого и последнего потомка;
- содержимое узлов должно быть набрано в математическом режиме.
Стиль может быть изменен, если одно или несколько из этих предположений требуют внесения поправок.
Вот код для дерева, который представляет собой небольшую адаптациюИгнаси:
\begin{forest}
state tree,
[x_0
[x_1
[x_{11}
[x_{111}]
[\dot{\cup}]
[x_{112}]
]
[\times]
[x_{12}
[x_{121}]
[\dot{\cup}]
[x_{122}]
]
]
[\dot{\cup}]
[x_2]
[\dot{\cup}]
[x_3
[x_{31}]
[\dot{\cup}]
[x_{32}]
[\dot{\cup}]
[x_{33}]
]
]
\end{forest}
state tree
задает стиль. Остальное происходит автоматически, поэтому нет необходимости в no edge
etc.
Это дает следующий результат:
Полный код:
\documentclass[border=10pt,multi,tikz]{standalone}
\usepackage{forest}
% ateb: addaswyd o ateb Ignasi: https://tex.stackexchange.com/a/351690/
\forestset{%
state tree/.style={%
for tree={
math content,
parent anchor=children,
child anchor=parent,
tier/.option=level,
calign=center,
},
where={>On>{n children}{2}}{
for nodewalk={
filter={children}{>On=!On=!&{n}{1}{n'}{1}}
}{no edge}
}{},
before computing xy={
where={isodd(n_children)}{
tempdima/.process={OOOw3+d{!n=1.s}{!n'=1.s}{n children}{(##2-##1)/(##3-1)}},
tempdimb/.option={!n=1.s},
for children={
s/.process={RROw3+d{tempdima}{tempdimb}{n}{##2+(##1*(##3-1))}}
},
}{},
},
},
}
\begin{document}
\begin{forest}
state tree,
[x_0
[x_1
[x_{11}
[x_{111}]
[\dot{\cup}]
[x_{112}]
]
[\times]
[x_{12}
[x_{121}]
[\dot{\cup}]
[x_{122}]
]
]
[\dot{\cup}]
[x_2]
[\dot{\cup}]
[x_3
[x_{31}]
[\dot{\cup}]
[x_{32}]
[\dot{\cup}]
[x_{33}]
]
]
\end{forest}
\end{document}
решение2
Вы также можете попробовать с forest
, хотя я не знаю, как правильно распределить некоторых детей:
\documentclass [multi=forest, border=2mm]{standalone}
\usepackage{forest}
\begin{document}
\begin{forest}
for tree={math content}
[x_0
[x_1
[x_{11}
[x_{111}]
[\dot{\cup}, no edge]
[x_{112}]]
[\times, no edge]
[x_{12}
[x_{121}]
[\dot{\cup}, no edge]
[x_{122}]]]
[\dot{\cup}, no edge]
[x_2, no edge]
[\dot{\cup}, no edge]
[x_3
[x_{31}]
[\dot{\cup}, no edge]
[x_{32}, no edge]
[\dot{\cup}, no edge]
[x_{33}]]]
\end{forest}
\end{document}
Обновление: с предложением JLDiaz результат выглядит лучше, все еще не идеально, но лучше.
\documentclass [multi=forest, border=2mm]{standalone}
\usepackage{forest}
\begin{document}
\begin{forest}
for tree={math content}
[x_0
[x_1
[x_{11}
[x_{111}]
[\dot{\cup}, no edge]
[x_{112}]]
[\null, no edge] %<-------------
[\times, no edge]
[x_{12}
[x_{121}]
[\dot{\cup}, no edge]
[x_{122}]]]
[\null, no edge] %<-------------
[\dot{\cup}, no edge]
[x_2, no edge]
[\dot{\cup}, no edge]
[x_3
[x_{31}]
[\dot{\cup}, no edge]
[x_{32}, no edge]
[\dot{\cup}, no edge]
[x_{33}]]]
\end{forest}
\end{document}
решение3
Первая попытка будет следующей. Я не очень опытен в рисовании деревьев, так что, возможно, есть лучший способ сделать это. Однако, ключевым моментом является размещение узлов между потомками, и библиотека calc
идеально подходит для этого:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\def\rootname{root}
\newcommand{\stnode}[3]{\node at ($(#1)!0.5!(#2)$) { #3 }}
\newcommand{\stnodec}[3]{\node at ($(#1.center)!0.5!(#2.center)$) { #3 }}
\newcommand{\stnoderootc}[3]{\node at ($(\rootname-#1.center)!0.5!(\rootname-#2.center)$) { #3 }}
\begin{document}
\begin{tikzpicture}
[
level 1/.style = {sibling distance = 3cm},
level 2/.style = {sibling distance = 2cm}
]
\node (root) { $x_0$ }
child { node { $x_1$ }
child { node { $x_3$ } }
child { node { $x_4$ } }
}
child { node { $x_2$ }
child { node { $x_5$ } }
child { node { $x_6$ } }
}
;
place the annotation nodes between the children
\stnode{root-1.center}{root-2.center}{$\times$};
\stnodec{root-1-1}{root-1-2}{$\times$};
\stnoderootc{2-1}{2-2}{$\times$};
\end{tikzpicture}
\end{document}
Вы можете использовать один из трех макросов ( \stnode
, \stnodec
(сenter), \stnoderootc
(автоматический корневой узел, центр)) для размещения узлов аннотации. Имя корня должно быть переопределено, чтобы представлять фактическое имя корневого узла. Для максимальной гибкости просто используйте \stnode
.
Аргументы: #1: первый узел, #2: второй узел, #3: текст узла.
Очевидно, что соответствующие узлы должны иметь одинаковое расположение по оси Y. Если это не так, то это все равно будет работать, но выглядеть это будет странно.