# Connecting line calculations with fitting node in 3D tikz?

Consider the following 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}


If I compile it as it is, I get the expected arrangement of nodes and connecting lines: But if I enable 3D by uncommenting the commented lines in the MWE, I get this: The NodeB text not being in perspective doesn't bother me all that much; what bothers me is that coordinates based on the NodeB fitting node rectangle do not work properly under 3D transformations (note that all is OK between "proper" nodes, e.g. the piece of the line going right into NodeC).

(I'm aware that this example, in particular, can be otherwise done without the fitting node rectangle - and so problem solved; the thing is, those are quite useful for GUI editing in TikzEdt, and so I have code with a ton of these all over the place; which is why I'd rather have a solution like a fix to the "fitting node" style instead. )

• – sdaau Mar 26 '14 at 19:09

I don't know where is the problem, may be transform shape is not applied to fit nodes. Here you have a workaround if nobody provides a better solution.

Use label={center:{node text}} as option for fitting nodes:

\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} • Many thanks for that @Ignasi - that fixes the text, but doesn't fix the lines. I'm poking around with this also, and it seems the problem is \pgftransformreset; I'm getting somewhere with \pgfgettransformentries{\ga}{\gb}{\gc}{\gd}{\gsx}{\gsy}\pgfsettransformentries{\ga}{\gb}{\gc}{\gd}{-10pt}{\gsx} instead of it, but my matrix math is a bit rusty, not sure I'll be able to bruteforce my way to a solution. Thanks again - cheers! – sdaau Mar 26 '14 at 17:02

EDIT: Note that this answer got broken in Texlive 2014 frozen:

Ok, I think I got it, but don't really understand why at the moment.

First, the problem is that fit does exactly what its told - we tell it to fit the last pgf min and max x and y, and it does exactly that (can be seen by changing into draw=red of fitting node): The problem seems to be, that the rectangle is already transformed by the time it gets to fit, and yet fit isn't aware of the 3D transform.

So I was trying to stop the transform, then do the rectangle fitting node, and then restore the transform - didn't work; tried to look for a way to group pgf drawing commands, and then apply a transform to all of them - couldn't find that.

Then I found #47797 How to establish node-anchor-like points on a (tikz) rectangle path (is there a better method than the one described)?, and used that so that coordinate anchors are added to the rectangle - and among other things, tried fit to the anchors of the rectangle... And suddenly it works?? And I cannot see how that would interrupt coordinate transformation, as was my theory for the problem above??

Nevertheless, the output now is: ... and while unfortunately, I will not be able to just change the fitting node style and move on (I'll have to add references to rectangles and corresponding fitting nodes everywhere) -- the code also works the same way it did in TikzEdt GUI, so that is good. The code is:

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

\makeatletter
%https://tex.stackexchange.com/a/47797/2595
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}