
Я пытаюсь нарисовать рисунок, который должен объяснить предложение.
das er das Lied wird haben singen müssen
что он песню придется петь должен
Идея состоит в том, чтобы записать предложение и получить дерево из кода ниже, которое показывает отношения доминирования, то есть какой глагол доминирует над каким другим глаголом. Прямо справа от singen я хочу иметь дополнительный узел для müssen, слева от него один для haben и слева от haben один для wird. Глаголы, которые находятся в деревьях, должны быть связаны с этими узлами стрелками. Возможно ли это? Я пробовал кое-что (см. код), но новые узлы не выходят на той же базовой линии, что и singen.
Может быть, мне придется все перерисовать как-то по-другому?
\documentclass{article}
\usepackage{tikz-qtree}
\begin{document}
\begin{tikzpicture}
\Tree [.wird
[.haben
[.muessen singen ] ] ] \node[anchor=east]{muessen};
\end{tikzpicture}
\end{document}
Вот как это должно выглядеть:
решение1
Простая идея: наберите предложение в matrix of nodes
. Этот тип объекта tikz автоматически присваивает имя каждому из его компонентов. В следующем примере я назвал матрицу M
, поэтому элементы первой (и единственной) строки называются M-1-1
, M-1-2
и так далее. Это позволяет легко добавлять больше слов поверх M-1-7
и устанавливать связи:
\usetikzlibrary{matrix, positioning}
\begin{tikzpicture}[shorten >=1mm]
\matrix[name=M, matrix of nodes, inner sep=0pt, column sep=1ex]{
dass & er & das & Lied & wird & haben & singen & m\"ussen \\
};
\node [anchor=base, above=2em of M-1-7.base] (mussen) {m\"ussen};
\node [anchor=base, above=2em of mussen.base] (haben) {haben};
\node [anchor=base, above=2em of haben.base] (wird) {wird};
\draw[->] (wird) to[out=180,in=90] (M-1-5);
\draw[->] (haben) to[out=180,in=90] (M-1-6);
\draw[->] (mussen) to[out=0,in=90] (M-1-8);
\draw (wird) --(haben) -- (mussen) -- (M-1-7);
\end{tikzpicture}
решение2
Хм, дерево выглядит не так. А как насчет цепей?
Мы устанавливаем две цепи:
- Цепь
sentence
идет направо,sentence going base right
, - Цепь
verbs
идет вверх,verbs going above
.
В sentence
цепочке мы просто размещаем части daß er das Lied
, wird
, haben
, singen
, können
для элементов, которые имеют умлаут или эсцет, мы назначаембезопасныйимя без них (возможны и другие решения, но они затруднят доступ к этим узлам). Если мы не укажем a \Name
в \foreach
цикле, \Item
текст будет просто использоваться.
Расстояние по горизонтали между узлами .3333em
задается так, чтобы узлы размещались так, как они размещались бы в предложении, для этого мы также устанавливаем inner xsep
и outer xsep
на ноль. Вы можете проверить это поведение, разместив другой узел так, чтобы он перекрывался с предложением:
\node[anchor=text] at (sentence-begin.text) {da\ss\space er das Lied wird haben singen k\"onnen};
Вертикальная часть node distance
, 1.5\baselineskip
, выбирается случайным образом, inner ysep
составляет половину размера по умолчанию. outer ysep
Также установлен на ноль (у нас нет нарисованных узлов).
Узлы вертикальной цепочки автоматически соединяются опцией join
(использующей every join
стиль). Соединения с узлами в предложении также производятся во втором цикле.
Специальный arc and line
стиль гарантирует, что дуги будут размером с четверть круга с максимально возможным радиусом. arc and line maximum
Однако можно задать необязательное значение.
Если мы установим arc and line maximum
очень маленькое значение, скажем 6pt
(значение по умолчанию для rounded corners
), мы можем имитировать базовый -|
путь с указанными закругленными углами. Нет необходимости в calc
библиотеке и let … in
прочем.
При arc and line maximum
установке на ноль мы получим базовый -|
путь с острыми углами. Как и выше, нам не понадобятся calc
и эти вычисления.
Лично мне больше нравится синий вариант с небольшим rounded corners
радиусом.
Код
\documentclass[tikz,convert=false]{standalone}
\usetikzlibrary{chains,calc}
\tikzset{
/pgf/arc and line maximum/.initial=+1000pt,
arc and line/.style={
to path={
let
\p{@end}=(\tikztotarget.north),
\p{@aux1}=($(\tikztostart)-(\p{@end})$),
\p{@start}=(node cs: name=\tikztostart, anchor={\x{@aux1} < 0pt ? +0 : +180}),
\n{@aux2}={min(\pgfkeysvalueof{/pgf/arc and line maximum},abs(\x{@start}-\x{@end}),abs(\y{@start}-\y{@end})-.1pt))}
in
{ [rounded corners=\n{@aux2}] -| (\tikztotarget) }
}},
special curve 0/.style={draw,->,arc and line},
special curve 1/.style={
special curve 0,
arc and line maximum=+6pt},
special curve 2/.style={
special curve 0,
arc and line maximum=+0pt},
every sentence and verb node/.style={
inner ysep=+.1667em,
outer ysep=+0pt},
sentence node/.style={
every sentence and verb node,
inner xsep=+0pt,
outer xsep=+0pt,
on chain=#1},
sentence node/.default=sentence,
verb node/.style={
every sentence and verb node,
on grid,
text depth=+0pt,
join,
on chain=#1},
verb node/.default=verbs
}
\begin{document}
\begin{tikzpicture}[
node distance=1.5\baselineskip and width(" ")*1pt,
start chain=sentence going base right,
start chain=verbs going above,
every join/.style={draw}
]
\foreach \Item/\Name in {da\ss\space er das Lied/dass,wird,haben,singen,k\"onnen/konnen}
\node [sentence node, alias=s-\Name] {\Item};
\chainin[on chain=verbs] (s-singen);
\foreach \Item/\Name in {k\"onnen/konnen,haben,wird} {
\node [verb node, alias=v-\Name] {\Item}
edge[special curve 2,green] (s-\Name)
edge[special curve 1,blue] (s-\Name)
edge[special curve 0] (s-\Name);
}
\end{tikzpicture}
\end{document}
Выход
решение3
Если вы \usetikzlibrary{positioning}
, вы можете определить узлы в терминах других узлов. Таким образом, если вы определяете узлы внутри дерева, вы можете расположить узлы снаружи дерева относительно узлов внутри дерева. Это означает, что вам придется вручную поиграться с интервалом, но это дает решение. Вот MWE, который должен вам подойти:
Обновлять: Как отмечает @Qrrbrbirlbel в комментариях, «g» в «singen» нарушает вертикальное выравнивание узлов относительно друг друга. Это было исправлено ниже с помощью base left
и base right
для выравнивания узлов друг относительно друга.
\documentclass{article}
\usepackage{qtree}
\usepackage{tikz}
\usepackage{tikz-qtree,tikz-qtree-compat}
\tikzset{every tree node/.style={align=center, anchor=north}}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}
\Tree [.\node(1){wird};
[.\node(2){haben};
[.\node(3){m\"{u}ssen}; \node(4){singen}; ] ] ]
\node(5)[base left=1.9cm of 4]{dass er das Lied};
\node(6)[base left=1.1cm of 4]{wird};
\node(7)[base left=.1cm of 4]{haben};
\node(8)[base right=.1cm of 4]{m\"{u}ssen};
\draw[->] (1)..controls +(west:1) and +(north:1)..(6);
\draw[->] (2)..controls +(west:1) and +(north:1)..(7);
\draw[->] (3)..controls +(east:1) and +(north:1)..(8);
\end{tikzpicture}
\end{document}