
Considere el siguiente 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}
Si lo compilo tal como está, obtengo la disposición esperada de nodos y líneas de conexión:
Pero si habilito 3D descomentando las líneas comentadas en MWE, obtengo esto:
Que el texto de NodeB no esté en perspectiva no me molesta mucho; Lo que me molesta es que las coordenadas basadas en el rectángulo del nodo de ajuste del NodoB no funcionan correctamente en transformaciones 3D (tenga en cuenta que todo está bien entre los nodos "adecuados", por ejemplo, el trozo de línea que va directamente al NodoC).
(Soy consciente de que este ejemplo, en particular, se puede hacer de otra manera sin el rectángulo del nodo adecuado, y así el problema se resuelve; la cuestión es que son bastante útiles para la edición de GUI en TikzEdt, por lo que tengo un código con una tonelada de estos por todas partes; es por eso que prefiero tener una solución como una solución para el estilo de "nodo de ajuste").
Respuesta1
No sé dónde está el problema, puede que transform shape
no se aplique a fit
los nodos. Aquí tiene una solución alternativa si nadie ofrece una solución mejor.
Usar label={center:{node text}}
como opción para fitting
nodos:
\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}
Respuesta2
EDITAR: Tenga en cuenta que esta respuesta se rompió en Texlive 2014 y se congeló:
Ok, creo que lo entendí, pero no entiendo por qué en este momento.
Primero, el problema es que fit
hace exactamente lo que se le dice: le decimos que se ajuste al último pgf min y max xey, y hace exactamente eso (se puede ver cambiando a draw=red
of fitting node
):
El problema parece ser que el rectángulo ya está transformado cuando llega a fit
, y aún fit
no es consciente de la transformación 3D.
Entonces estaba tratando de detener la transformación, luego hacer el nodo de ajuste del rectángulo y luego restaurar la transformación; no funcionó; Intenté buscar una manera de agrupar los comandos de dibujo de pgf y luego aplicar una transformación a todos ellos, pero no pude encontrarlo.
Entonces encontré#47797 ¿Cómo establecer puntos similares a anclajes de nodos en una ruta rectangular (tikz) (existe un método mejor que el descrito)?, y lo usé para agregar anclajes de coordenadas al rectángulo, y entre otras cosas, probé fit
los anclajes del rectángulo... ¿Y de repente funciona? ¿Y no veo cómo eso interrumpiría la transformación de coordenadas, como era mi teoría para el problema anterior?
Sin embargo, el resultado ahora es:
... y aunque, desafortunadamente, no podré simplemente cambiar el fitting node
estilo y seguir adelante (tendré que agregar referencias a rectángulos y nodos de ajuste correspondientes en todas partes): el código también funciona de la misma manera que en TikzEdt GUI. , entonces eso es bueno. El código es:
\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}