Desalinhamento de nós TikZ ao usar posicionamento

Desalinhamento de nós TikZ ao usar posicionamento

Ao posicionar vários nós contendo imagens TikZ em relação uns aos outros (usando a positioningbiblioteca TikZ), parece que os nós nas imagens contidas ficam ligeiramente desalinhados:

Desalinhamento de nós

Esta imagem resulta do seguinte código

\documentclass{article}

\usepackage{tikz}
\usepackage{fp}

\usetikzlibrary{positioning}

\tikzstyle{vertex}=[circle, fill=black, minimum size=2pt, inner sep=0pt]

\newcommand{\makeTikzTree}[1]{%
    \FPeval{\result}{#1/2}
    \begin{tikzpicture}[thick, scale=0.4]
        \draw (0, 0) -- (0, -1) node[vertex]{};
        \ifodd#1
            \draw (0, 1) node[vertex]{} -- (0, 0);
            \foreach \x in {1, ..., \result} {
                \draw (-\x, 1) node[vertex]{} -- (0, 0);
                \draw (\x, 1) node[vertex]{} -- (0, 0);
            }
        \else
            \foreach \x in {0.5, ..., \result} {
                \draw (-\x, 1) node[vertex]{} -- (0, 0);
                \draw (\x, 1) node[vertex]{} -- (0, 0);
            }
        \fi
    \end{tikzpicture}
}

\begin{document}
\begin{center}
    \begin{tikzpicture}
        \node (tree1) {\makeTikzTree{5}};
        \node [right=of tree1] (tree2) {\makeTikzTree{4}};
        \node [right=of tree2] (tree3) {\makeTikzTree{7}};
    \end{tikzpicture}
\end{center}
\end{document}

Observe como o alinhamento na primeira árvore está correto. O que está acontecendo aqui? Como isso funciona bem ao especificar posições absolutas para os nós, mas não com posicionamento relativo?

Responder1

Infelizmente, seu código aninha tikzpictures. Isto deve ser evitado porque os valores das chaves pgf da imagem ambiente são herdados. Você também não precisa fazer isso, TikZ tem pics para esse propósito. Mesmo assim, você precisa ter certeza de que vertexnão herdará a âncora do posicionamento. rightimplica que a âncora é west, o que explica que todos os vértices são conectados à sua esquerda. Você pode evitar isso adicionando anchor=centeràs opções de vertex.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\begin{document}
\begin{center}
    \begin{tikzpicture}[vertex/.style={circle, fill=black, minimum
    size=2pt,inner sep=0pt,anchor=center},
        pics/little tree/.style={code={
         \pgfmathtruncatemacro{\xmax}{#1/2}
         \draw (0, 0) -- (0, -1) node[vertex]{};
        \ifodd#1
            \draw (0, 1) node[vertex]{} -- (0, 0);
            \foreach \x in {1, ..., \xmax} {
                \draw (-\x, 1) node[vertex]{} -- (0, 0);
                \draw (\x, 1) node[vertex]{} -- (0, 0);
            }
        \else
            \foreach \x in {0.5, ..., \xmax} {
                \draw (-\x, 1) node[vertex]{} -- (0, 0);
                \draw (\x, 1) node[vertex]{} -- (0, 0);
            }
        \fi}}]
        \node[matrix] (tree1) {\pic[scale=0.4]{little tree=5};\\};
        \node[matrix,right=of tree1] (tree2) {\pic[scale=0.4]{little tree=4};\\};
        \node[matrix,right=of tree2] (tree3) {\pic[scale=0.4]{little tree=7};\\};
    \end{tikzpicture}
\end{center}
\end{document}

insira a descrição da imagem aqui

Responder2

Como fez o gato de Schrödinger, eu implementaria suas árvores como um arquivo pic. Você pode simplificar seu código como:

\tikzset{
  vertex/.style={circle, fill=black, minimum size=2pt, inner sep=0pt},
  pics/tree/.style = {
      code = {
      \begin{scope}[scale=0.4, thick]
        \node[vertex] (0) at (0,0){};
        \draw(0)--(0,1);
        \foreach \x in {1,...,#1} {
          \node[vertex] (n\x) at (\x-#1/2-1/2,2){};
          \draw(0,1)--(n\x);
        }
      \end{scope}
    }
  }
}

Em particular, observe que você não precisa \FPevalnem deve usar arquivos \ifodd. Além disso, \tikzstylefoi depreciado em favor de \tikzset.

Com isso implementado, meu entendimento da biblioteca de posicionamento a partir de exemplos é que o código a seguir deve funcionar

\begin{tikzpicture}
  \pic (tree1) at (0,0){tree=5};
  \pic[right=of tree1] (tree2) {tree=4};
  \pic[right=of tree2] (tree3) {tree=7};
\end{tikzpicture}

mas por motivos que não entendo isso dá erro. Em vez de usar o positioning libraryeu prefiro plantar as árvores manualmente para dar:

insira a descrição da imagem aqui

Alternativamente, você pode usar o belo truque do gato de Schrödinger:

\begin{tikzpicture}
  \node[matrix] (tree1) {\pic{tree=5};\\};
  \node[matrix,right=of tree1] (tree2) {\pic{tree=4};\\};
  \node[matrix,right=of tree2] (tree3) {\pic{tree=7};\\};
\end{tikzpicture} 

Aqui está o código completo:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}

\tikzset{
  vertex/.style={circle, fill=black, minimum size=2pt, inner sep=0pt},
  pics/tree/.style = {
      code = {
      \begin{scope}[scale=0.4, thick]
        \node[vertex] (0) at (0,0){};
        \draw(0)--(0,1);
        \foreach \x in {1,...,#1} {
          \node[vertex] (n\x) at (\x-#1/2-1/2,2){};
          \draw(0,1)--(n\x);
        }
      \end{scope}
    }
  }
}

\begin{document}
  \begin{center}
      \begin{tikzpicture}
        \pic at (0,0){tree=5};
        \pic at (2,0){tree=4};
        \pic at (4.5,0){tree=7};
      \end{tikzpicture}
  \end{center}

  % Schrödinger's cat's nice trick
  \begin{tikzpicture}
    \node[matrix] (tree1) {\pic{tree=5};\\};
    \node[matrix,right=of tree1] (tree2) {\pic{tree=4};\\};
    \node[matrix,right=of tree2] (tree3) {\pic{tree=7};\\};
  \end{tikzpicture} 

\end{document}

informação relacionada