Краткое содержание:

Краткое содержание:

Краткое содержание:

Есть ли способ измерить ширину листового узла и передать это измерение обратно вверх по дереву для использования в настройке 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}

Здесь я непосредственно измеряю ширинудействительныйleaves и пытаюсь использовать это для установки sibling distanceв корневом узле. К сожалению, это дает ошибку "Undefined control sequence. <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)математической библиотеки. Здесь я убрал макросы и использовал решение Янниса без какой-либо автоматизации.

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

введите описание изображения здесь

Связанный контент