我有很有帮助先前使用定义树forest
(再次感谢 cfr!)。
我希望能够将一棵树分解成子树并在它们之间建立链接……无论是在同一片森林中还是在分离的森林中。
图片将更加容易理解...
从 :
初始 http://www.weboplanet.com/tests/calculerAire2disques.pdf.png
类似于:
类似的东西http://www.weboplanet.com/tests/calculerAire2disques.pdf_wish.png
我尝试使用“幻影”节点作为根,但子树保持在同一行:
类似的东西http://www.weboplanet.com/tests/calculerAire2disques_wish_resultat.pdf.png
源代码 :
\documentclass{standalone}
\usepackage[latin1]{inputenc}
\usepackage{forest}
\usetikzlibrary{shapes.geometric}
\begin{document}
\pgfkeys{/forest,
decision/.append style={diamond, fill=blue!20, text width=5em, inner sep=.5pt, rounded corners},
io/.append style={trapezium, trapezium left angle=70,trapezium right angle=-70, minimum height=5mm},
sequence/.append style={fill=red!20, rounded corners},
nop/.append style={fill=red!5},
rotor/.append style={inner sep=3pt,outer sep=0,fill opacity=0.3,minimum width=2cm,circle},
racine/.append style={minimum width=1cm, fill=white!80,circle,
tikz={
\draw [circle,draw,line width=0.5pt] ;
\draw [->,line width=1pt] () ++(160:4mm) arc (-200:40:4mm);}
}
}
\begin{forest}for tree={
child anchor=north,
parent anchor=south,
thick,
draw,
align=center,
font=\sffamily\large,
}
[,phantom
[{Principal\\\hline \mbox{}\\[-1em]reel r1, r2, aire2, PI\\reel aire1, aire\\}
[seq, racine
[initialisation, name=initSrc,sequence
]
[Traitement, name=trtSrc,sequence
]
[Resultat, name=resSrc,sequence
]
]
]
[initialisation, name=initDest,sequence
[{ECRIRE "rayon du disque extérieur ?"}, io]
[{r1$\leftarrow$ LIRE()}, io]
[{ECRIRE "rayon du disque interieur ?"}, io]
[{r2$\leftarrow$ LIRE()}, io]
]
[Traitement, name=trtDest,sequence
[{aire1$\leftarrow$ PI*r1*r1} ]
[{aire2$\leftarrow$ PI*r2*r2} ]
[{aire$\leftarrow$ r1-r2} ]
]
[Resultat, name=resDest,sequence
[{ECRIRE "l'aire vaut ",aire}, io]
]
]
\draw[->] (initSrc) to[out=north east,in=south] (initDest);
\draw[->] (trtSrc) to[out=north east,in=south] (trtDest);
\draw[->] (resSrc) to[out=north east,in=south] (resDest);
\end{forest}
\end{document}
非常感谢您的帮助 !
答案1
您可以尝试类似这样的方法。此解决方案使用phantom
节点与fit=rectangle
和的组合calign with current
来排列事物,并确保箭头不会穿过节点和连接线。基本思想是将子树创建为左侧分支的子树,但使用phantom
节点来创建,这样它们就不会看就像排版结果中的子树。
\documentclass{standalone}
\usepackage[utf8]{inputenc}
\usepackage{forest}
\usetikzlibrary{shapes.geometric}
\begin{document}
\pgfkeys{/forest,
decision/.append style={diamond, fill=blue!20, text width=5em, inner sep=.5pt, rounded corners},
io/.append style={trapezium, trapezium left angle=70,trapezium right angle=-70, minimum height=5mm},
sequence/.append style={fill=red!20, rounded corners},
nop/.append style={fill=red!5},
rotor/.append style={inner sep=3pt,outer sep=0,fill opacity=0.3,minimum width=2cm,circle},
racine/.append style={minimum width=1cm, fill=white!80,circle,
tikz={
\draw [circle,draw,line width=0.5pt] ;
\draw [->,line width=1pt] () ++(160:4mm) arc (-200:40:4mm);}
}
}
\begin{forest}for tree={
child anchor=north,
parent anchor=south,
thick,
draw,
align=center,
font=\sffamily\large,
}
[{Principal\\\hline \mbox{}\\[-1em]reel r1, r2, aire2, PI\\reel aire1, aire\\}
[seq, racine
[initialisation, name=initSrc,sequence, fit=rectangle
[,phantom
[initialisation, name=initDest,sequence
[{ECRIRE "rayon du disque extérieur ?"}, io]
[{r1$\leftarrow$ LIRE()}, io]
[,phantom, calign with current
[,phantom, calign with current
[Traitement, name=trtDest,sequence
[{aire1$\leftarrow$ PI*r1*r1} ]
[{aire2$\leftarrow$ PI*r2*r2}, calign with current
[,phantom, calign with current
[Resultat, name=resDest,sequence
[{ECRIRE "l'aire vaut ",aire}, io]
]
]
]
[{aire$\leftarrow$ r1-r2} ]
]
]
]
[{ECRIRE "rayon du disque interieur ?"}, io]
[{r2$\leftarrow$ LIRE()}, io]
]
]
]
[Traitement, name=trtSrc,sequence
]
[Resultat, name=resSrc,sequence
]
]
]
]
\draw[->] (initSrc) to[out=south east,in=north] (initDest);
\draw[->] (trtSrc) to[out=south east,in=east] (trtDest);
\draw[->] (resSrc) to[out=south east,in=east] (resDest);
\end{forest}
\end{document}
答案2
根据@cfr 的回答,我将使用'幻影' 节点加法升设置节点垂直位置的选项:
优势:多级节点时容易改变
缺点:跨框链接
编辑:我记住@cfr 的评论:“...森林不是设计用来布局断开的节点的...”,但对我来说,使用下面的解决方案会更容易,直到我可以使用不同分层森林之间的链接。
代码:(仅森林区块,其余不变)
...
\begin{forest}
for tree={
child anchor=north,
parent anchor=south,
thick,
draw,
align=center,
font=\sffamily\large
}
[,phantom
[{Principal\\\hline \mbox{}\\[-1em]reel r1, r2, aire2, PI\\reel aire1, aire\\}
[seq, racine
[Initialisation , name=initSrc,sequence
]
[Traitement, name=trtSrc,tier=bottom,sequence
]
[Resultat, name=resSrc,sequence
]]]
[,phantom, l*=6
[Initialisation, name=initDest,sequence
[{ECRIRE "rayon du disque extérieur ?"}, io]
[{r1$\leftarrow$ LIRE()}, io]
[{ECRIRE "rayon du disque interieur ?"}, io]
[{r2$\leftarrow$ LIRE()}, io]
]]
[,phantom,l*=9
[Traitement, name=trtDest,sequence
[{aire1$\leftarrow$ PI*r1*r1} ]
[{aire2$\leftarrow$ PI*r2*r2} ]
[{aire$\leftarrow$ r1-r2} ]
]]
[,phantom, l*=12
[Resultat, name=resDest,sequence
[{ECRIRE "l'aire vaut ",aire}, io]
]]
]
\draw[->>,dashed] (initSrc) to[out=south,in=west] (initDest);
\draw[->>,dashed] (trtSrc) to[out=south east,in=east] (trtDest);
\draw[->>,dashed] (resSrc) to[out=south,in=east] (resDest);
\end{forest}
....
图像 :
解决方案保留 http://www.weboplanet.com/tests/calculerAire2disques_wish.pdf_final.png