Conectando cálculos de linha com nó de ajuste em tikz 3D?

Conectando cálculos de linha com nó de ajuste em tikz 3D?

Considere o seguinte MWE:

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{positioning}
\usetikzlibrary{fit}
\usetikzlibrary{3d}

\makeatletter
\tikzset{
  fitting node/.style={
    inner sep=0pt,
    fill=none,
    draw=none,
    reset transform,
    fit={(\pgf@pathminx,\pgf@pathminy) (\pgf@pathmaxx,\pgf@pathmaxy)}
  },
  reset transform/.code={\pgftransformreset},
}
\makeatother
\tikzstyle{dr} = [draw, rectangle, line width=1pt, font=\Huge, align=left]
\tikzstyle{cl} = [>=latex,->,line width=1pt]

\begin{document}
\begin{tikzpicture}[
%   x={(0.5cm,0.5cm)}, y={(1cm,0cm)}, z={(0cm,1cm)},
%   every node/.append style={transform shape},
]

\draw[very thick] (0,0) rectangle (18,8) node[fitting node] (starter) {};

\begin{scope}[
  shift={(1,1)},
%   canvas is yx plane at z=0.25,
]
\node[dr] (NodeA) at (1,5) {Node A};
\draw[dr] (4.5,2.5) rectangle (11,6.5) node [fitting node] (NodeB) {Node B\\Slightly bigger};
\node[dr] (NodeC) [above=10pt of NodeB.south, anchor=south] {Node C};

\draw[cl] (NodeA) -- (NodeB);
\draw[cl] (NodeA) |- ($(NodeB.north west)-(10pt,10pt)$) -- ($(NodeB.south west)-(10pt,7.5pt)$) -| ($(NodeC.south west)+(10pt,0)$);

\end{scope}
\end{tikzpicture}
\end{document}

Se eu compilar como está, obtenho a disposição esperada de nós e linhas de conexão:

teste41.png

Mas se eu habilitar o 3D descomentando as linhas comentadas no MWE, recebo o seguinte:

teste42.png

O fato de o texto do NodeB não estar em perspectiva não me incomoda muito; o que me incomoda é que as coordenadas baseadas no retângulo do nó de ajuste do NodeB não funcionam corretamente nas transformações 3D (observe que está tudo OK entre os nós "adequados", por exemplo, o pedaço da linha que vai direto para o NodeC).

(Estou ciente de que este exemplo, em particular, pode ser feito de outra forma sem o retângulo do nó apropriado - e assim o problema foi resolvido; o problema é que eles são bastante úteis para edição de GUI no TikzEdt, e por isso tenho código com uma tonelada de isso está em todo lugar; é por isso que prefiro uma solução como uma correção para o estilo "nó de ajuste").

Responder1

Não sei onde está o problema, pode transform shapenão ser aplicado aos fitnós. Aqui você tem uma solução alternativa se ninguém fornecer uma solução melhor.

Use label={center:{node text}}como opção para fittingnós:

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{positioning}
\usetikzlibrary{fit}
\usetikzlibrary{3d}

\makeatletter
\tikzset{
  fitting node/.style={
    inner sep=0pt,
    fill=none,
    draw=none,
    reset transform,
    fit={(\pgf@pathminx,\pgf@pathminy) (\pgf@pathmaxx,\pgf@pathmaxy)}
  },
  reset transform/.code={\pgftransformreset},
}
\makeatother
\tikzstyle{dr} = [draw, rectangle, line width=1pt, font=\Huge, align=left]
\tikzstyle{cl} = [>=latex,->,line width=1pt]

\begin{document}
\begin{tikzpicture}[
   x={(0.5cm,0.5cm)}, y={(1cm,0cm)}, z={(0cm,1cm)},
   every node/.append style={transform shape},
]

\draw[very thick] (0,0) rectangle (18,8) node[fitting node] (starter) {};

\begin{scope}[
  shift={(1,1)},
   canvas is yx plane at z=0.25,
]
\node[dr] (NodeA) at (1,5) {Node A};
\draw[dr] (4.5,2.5) rectangle (11,6.5) node [fitting node, label={center:{Node B\\Slightly bigger}}] (NodeB) {};
\node[dr] (NodeC) [above=10pt of NodeB.south, anchor=south] {Node C};

\draw[cl] (NodeA) -- (NodeB);
\draw[cl] (NodeA) |- ($(NodeB.north west)-(10pt,10pt)$) -- ($(NodeB.south west)-(10pt,7.5pt)$) -| ($(NodeC.south west)+(10pt,0)$);

\end{scope}
\end{tikzpicture}
\end{document}

insira a descrição da imagem aqui

Responder2

EDIT: Observe que esta resposta foi quebrada no Texlive 2014 congelado:

Ok, acho que entendi, mas realmente não entendo o porquê no momento.

Primeiro, o problema é que ele fitfaz exatamente o que foi dito - dizemos para ele ajustar o último pgf min e max x e y, e ele faz exatamente isso (pode ser visto mudando para draw=redof fitting node):

teste43.png

O problema parece ser que o retângulo já está transformado quando chega fite ainda fitnão está ciente da transformação 3D.

Então, eu estava tentando interromper a transformação, fazer o nó de ajuste do retângulo e restaurar a transformação - não funcionou; tentei procurar uma maneira de agrupar comandos de desenho pgf e, em seguida, aplicar uma transformação a todos eles - não consegui encontrar isso.

Então eu encontrei#47797 Como estabelecer pontos tipo âncora de nó em um caminho retangular (tikz) (existe um método melhor que o descrito)?, e usei isso para que as âncoras coordenadas fossem adicionadas ao retângulo - e entre outras coisas, tentei fitas âncoras do retângulo... E de repente funciona?? E não consigo ver como isso interromperia a transformação de coordenadas, como foi minha teoria para o problema acima?

No entanto, a saída agora é:

teste44.png

... e embora, infelizmente, não poderei simplesmente mudar o fitting nodeestilo e seguir em frente (terei que adicionar referências a retângulos e nós de ajuste correspondentes em todos os lugares) - o código também funciona da mesma maneira que na GUI do TikzEdt , então isso é bom. O código é:

\usetikzlibrary{calc}
\usetikzlibrary{positioning}
\usetikzlibrary{fit}
\usetikzlibrary{3d}

\makeatletter
%https://tex.stackexchange.com/a/47797/2595
\tikzset{add reference/.style={insert path={%
    coordinate [pos=0,xshift=-0.5\pgflinewidth,yshift=-0.5\pgflinewidth] (#1 south west)
    coordinate [pos=1,xshift=0.5\pgflinewidth,yshift=0.5\pgflinewidth]   (#1 north east)
    coordinate [pos=.5] (#1 center)
    (#1 south west |- #1 north east)     coordinate (#1 north west)
    (#1 center     |- #1 north east)     coordinate (#1 north)
    (#1 center     |- #1 south west)     coordinate (#1 south)
    (#1 south west -| #1 north east)     coordinate (#1 south east)
    (#1 center     -| #1 south west)     coordinate (#1 west)
    (#1 center     -| #1 north east)     coordinate (#1 east)
}}}
\tikzset{
  fitting node/.style={
    inner sep=0pt,
    fill=none,
    draw=red,
    fit={(#1 south west) (#1 north east)},
  },
}
\makeatother
\tikzstyle{dr} = [draw, rectangle, line width=1pt, font=\Huge, align=left]
\tikzstyle{cl} = [>=latex,->,line width=1pt]


\begin{tikzpicture}[
  x={(0.5cm,0.5cm)}, y={(1cm,0cm)}, z={(0cm,1cm)},
  every node/.append style={transform shape},
]

\draw[very thick] (0,0) rectangle (18,8) [add reference=R1] node[fitting node=R1] (starter) {};

\begin{scope}[
  shift={(1,1)},
  canvas is yx plane at z=0.25,
]
\node[dr] (NodeA) at (1,5) {Node A};

\draw[dr] (4.5,2.5) rectangle (11,6.5) [add reference=R2] node [fitting node=R2] (NodeB) {Node B\\Slightly bigger};

\node[dr] (NodeC) [above=10pt of NodeB.south, anchor=south] {Node C};

\draw[cl] (NodeA) -- (NodeB);
\draw[cl] (NodeA) |- ($(NodeB.north west)-(10pt,10pt)$) -- ($(NodeB.south west)-(10pt,7.5pt)$) -| ($(NodeC.south west)+(10pt,0)$);

\end{scope}
\end{tikzpicture}

informação relacionada