TL;DR 摘要:

TL;DR 摘要:

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}

在此輸入影像描述

相關內容