TL;DR摘要:
是否有某种方法可以测量叶节点的宽度,并将该测量值传递回树以用于设置?(人们可能也sibling distance
想做类似的事情。)level distance
例子:
假设我有一棵简单的树,其中每个叶节点都包含相同的图像:
\documentclass{standalone}
\usepackage{tikz}
\pgfdeclareimage{image}{fptp-ballot}
\begin{document}
\begin{tikzpicture}
\node {root} [level/.append style={level distance=4cm}]
child foreach \c in {1,2} {
node [fill=red!10] {\pgfuseimage{image}}};
\end{tikzpicture}
\end{document}
使用 的默认设置sibling distance
,叶子重叠:
测量叶子宽度的一种方法是创建一个不可见的临时叶子,tmp
然后使用let
路径操作来计算其宽度:
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\pgfdeclareimage{image}{fptp-ballot}
\begin{document}
\begin{tikzpicture}
\node (tmp) [fill=red!10, transparent, overlay] {\pgfuseimage{image}};
\path let \p{leafwidth} = ($(tmp.east)-(tmp.west)$) in
node {root} [level/.append style={level distance=4cm, sibling distance=\x{leafwidth}}]
child foreach \c in {1,2} {
node [fill=red!10] {\pgfuseimage{image}}};
\end{tikzpicture}
\end{document}
这种方法的问题是:tmp
当我真正想要测量的叶子在代码中已经存在时,需要创建一个临时的叶子似乎很笨拙。这会让事情变得不那么模块化。如果我改变叶子,那么我需要tmp
相应地改变节点(或者用宏和样式分解出叶子代码)。
换句话说,我想要一个可行的解决方案本地不管我在叶子里面放了什么——单个图像、具有任意细胞内容的矩阵等等。
问题:
有没有办法直接测量实际的叶节点并将该测量值传递回树以用于设置sibling distance
?
我想写如下内容:
\begin{tikzpicture}
\node {root} [level/.append style={level distance=4cm, sibling distance=\x{leaf1width}}]
child foreach \c in {1,2} {
node (leaf\c)
[fill=red!10] {\pgfuseimage{image}}
let \p{leaf\c width} = ($(leaf\c.east)-(leaf\c.west)$) in};
\end{tikzpicture}
这里我直接测量实际的叶子节点,并尝试使用它来设置sibling distance
根节点。不幸的是,这给出了错误“未定义的控制序列。 <argument> \x{leaf1width}
”,大概是因为\p{leaf\c width}
在到达叶子节点之前未定义。有什么方法可以修复此代码吗?
我想过使用late options
钥匙,但是TikZ 手册指出
确定一个已经存在的节点 [...] 然后,选项将在本地范围内执行。大多数这些选项将不起作用,因为您无法更改节点的外观,也就是说,您不能使用后期选项将红色节点更改为绿色节点。
的确,下面的编译没有错误,但sibling distance
不受影响。
\begin{tikzpicture}
\node (root) {root} [level/.append style={level distance=4cm}]
child foreach \c in {1,2} {
node (leaf\c)
[fill=red!10] {\pgfuseimage{image}}
let \p{leaf\c width} = ($(leaf\c.east)-(leaf\c.west)$) in
(root) [late options={level/.append style={sibling distance=\x{leaf1width}}}]};
\end{tikzpicture}
答案1
正如评论中所链接的,先将图像放入一个框中可以很容易地测量图像的大小。我不确定我是否理解了其中的复杂性,但如果您只有少量图像可以放入树中,那么您可以通过max(x,y)
数学库获取这些测量的最大值。在这里,我删除了宏并使用了 Yiannis 的解决方案,没有任何自动化。
\documentclass{standalone}
\usepackage{tikz}
\newsavebox{\Image}
\savebox{\Image}{\includegraphics[scale=0.05]{DSOTM}}
\newlength{\imageh}
\newlength{\imagew}
\settoheight{\imageh}{\usebox{\Image}}
\settowidth{\imagew}{\usebox{\Image}}
\begin{document}
\begin{tikzpicture}
\node {root} [level/.append style={
level distance=1.5\imageh, sibling distance=1.1\imagew
}
]
child foreach \c in {1,2} {
node [fill=red!10,inner sep=1pt] {\includegraphics[scale=0.05]{DSOTM}}};
\end{tikzpicture}
\end{document}