Resumo TL; DR:

Resumo TL; DR:

Resumo TL; DR:

Existe alguma maneira de medir a largura de um nó folha e passar essa medida de volta à árvore para ser usada na configuração sibling distance? (Poderíamos querer fazer algo semelhante level distancetambém.)

Exemplo:

Suponha que eu tenha uma árvore simples onde cada nó folha contém a mesma imagem:

\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}

Com a configuração padrão para sibling distance, as folhas se sobrepõem:

insira a descrição da imagem aqui

Uma maneira de medir a largura da folha é criar uma folha temporária invisível, tmpe usar a letoperação para caminhos para calcular sua largura:

\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}

insira a descrição da imagem aqui

O problema dessa abordagem é: parece estranho precisar criar uma folha temporária, tmp, quando as folhas que eu realmente quero medir já existem posteriormente no código. Isso torna as coisas menos modulares. Se eu alterar as folhas, precisarei alterar o tmpnó correspondentemente (ou fatorar o código da folha com uma macro e um estilo).

Em outras palavras, gostaria de uma solução que funcionasselocalmenteindependentemente do que coloquei dentro das folhas - uma única imagem, uma matriz com conteúdo de célula arbitrário, etc.

Pergunta:

Existe alguma maneira de medir diretamente a largura de umrealnó folha e passe essa medida de volta à árvore para ser usada na configuração sibling distance?

Eu gostaria de escrever algo como o seguinte:

\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}

Aqui estou medindo diretamente as larguras dorealsai e estou tentando usar isso para definir sibling distanceno nó raiz. Infelizmente, isso gera o erro "Sequência de controle indefinida. <argument> \x{leaf1width}", provavelmente porque \p{leaf\c width}não está definido até que as folhas sejam alcançadas. Existe alguma maneira de corrigir esse código?

Pensei em usar a late optionschave, mas oManual do TikZafirma que

É determinado um nó já existente [...] e, então, as opções são executadas em escopo local. A maioria dessas opções não terá efeito, pois vocênão é possível alterar a aparência do nó, ou seja, você não pode transformar um nó vermelho em um nó verde usando opções posteriores.

Na verdade, o seguinte é compilado sem erros, mas sibling distancenão é afetado.

\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}

Responder1

Conforme vinculado nos comentários, colocar primeiro suas imagens em uma caixa torna muito fácil medir o tamanho da imagem. Não tenho certeza se entendi a complicação, mas se você tiver poucas imagens que entrariam na árvore, poderá tirar o máximo dessas medidas na max(x,y)biblioteca matemática. Aqui eliminei as macros e usei a solução da Yiannis sem qualquer automação.

\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}

insira a descrição da imagem aqui

informação relacionada