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、葉は重なり合います。

ここに画像の説明を入力してください

葉の幅を測定する 1 つの方法は、目に見えない一時的な葉 を作成しtmpletパスの演算を使用してその幅を計算することです。

\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 マニュアルと述べています

すでに存在するノードが決定され、オプションはローカルスコープで実行されます。これらのオプションのほとんどは、ノードの外観を変更できませんつまり、late オプションを使用して赤いノードを緑のノードに変更することはできません。

実際、次のコードはエラーなしでコンパイルされますが、 は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}

ここに画像の説明を入力してください

関連情報