在 3D tikz 中将线计算与拟合节点连接起来?

在 3D tikz 中将线计算与拟合节点连接起来?

考虑以下 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}

如果我按原样编译它,我会得到预期的节点和连接线排列:

测试41.png

但是,如果我通过取消注释 MWE 中的注释行来启用 3D,我会得到以下信息:

测试42.png

NodeB 文本不在透视图中并没有让我感到太困扰;令我困扰的是基于 NodeB 拟合节点矩形的坐标在 3D 变换下不能正常工作(请注意,“正确”节点之间一切都正常,例如进入 NodeC 的那段线)。

(我知道,特别是这个例子可以在没有拟合节点矩形的情况下完成 - 这样问题就解决了;问题是,它们对于 TikzEdt 中的 GUI 编辑非常有用,所以我到处都有大量这样的代码;这就是为什么我宁愿有一个像修复“拟合节点”样式的解决方案。)

答案1

我不知道问题出在哪里,可能是transform shape没有应用到fit节点。如果没有人提供更好的解决方案,这里有一个解决方法。

用作节点label={center:{node text}}的选项fitting

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

在此处输入图片描述

答案2

编辑:请注意,这个答案在 Texlive 2014 冻结中被破坏了:

好的,我想我明白了,但目前还不太明白为什么。

首先,问题是它fit完全按照要求去做 - 我们告诉它适合最后一个 pgf 最小值和最大值 x 和 y,它确实做到了这一点(可以通过更改为draw=redof来看到fitting node):

测试43.png

问题似乎是,矩形在到达时已经变换了fit,但却fit没有意识到 3D 变换。

因此我尝试停止变换,然后执行矩形拟合节点,然后恢复变换 - 但是没有奏效;尝试寻找一种方法来对 pgf 绘图命令进行分组,然后对它们全部应用变换 - 但是没有找到。

然后我发现#47797 如何在(tikz)矩形路径上建立节点锚点(有没有比描述的方法更好的方法)?,并利用它将坐标锚点添加到矩形中 - 除其他外,还尝试fit将其添加到矩形的锚点... 突然就起作用了??我看不出这会如何中断坐标转换,就像我对上述问题的理论一样??

尽管如此,现在的输出是:

测试44.png

... 不幸的是,我不能只改变样式fitting node然后继续(我必须在各处添加对矩形和相应拟合节点的引用)——代码的工作方式也与 TikzEdt GUI 中相同,所以这很好。代码是:

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

相关内容