
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 distance
també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:
Uma maneira de medir a largura da folha é criar uma folha temporária invisível, tmp
e usar a let
operaçã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}
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 tmp
nó 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 distance
no 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 options
chave, 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 distance
nã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}