在 TiKz 中计算节点和连接的中间坐标

在 TiKz 中计算节点和连接的中间坐标

这是我想要做的一部分。请记住,在原始版本中,框/节点的宽度是可变的,并且链 B 和 C 的长度并非每次都相同。

% ---    ---     ---
% |A|    |B|     |C|
% ---    ---     ---
%  |      |  ---  |
%  |      |--|X|--|
%  |      |  ---  |
%  |     ---     ---
%  |     |b|     |c|
%  |     ---     ---
%  |      |       |
%  |      |  ---  |
%  ----------|E|---    
%            ---

我在网上和文档中找到了 TiKz 的一些示例。阅读时我理解它们,但我无法将其转移到我自己的代码中。我的问题之一是如何计算框的正确坐标X。应该有某种(B.x+.5,B.y+.5)。再进一步,当我尝试绘制线条时,例如从到和X之间的线的中间,我遇到了一个无缝问题。我确信我并不真正了解包的所有细节。我甚至不确定这是否是满足我需求的正确选择。也许另一个坐标系会更好?Bbcalc

\documentclass{article}
% TiKz
\usepackage{tikz}
\usetikzlibrary{chains,scopes,positioning,calc}

\begin{document}
\begin{tikzpicture}
    [
        every node/.style={
            draw,
            align=center},
        every join/.style=->
    ]
    \node (A) {A};

    {[start chain=B going below,
      every node/.append style=join]
        \node (B) [on chain,right=of A] {B};
        \node [on chain] {b};
    }

    {[start chain=C going below,
      every node/.append style=join]
        \node (C) [on chain,right=of B] {C};
        \node [on chain] {c};
    }

    % from here I am out of solutions!
    \node (X) at ($(B-1)!0.5!(C-1)$) {X};

    \node (E) at ($(B-2)!0.5!(C-2)$) {E};

    \draw [->] (A) |- (E);
\end{tikzpicture}
\end{document}

答案1

命名小写节点后,计算可以嵌套在一起,如下所示。我添加了节点\vphantom{b}的文本c,因此它与邻居的高度相同。

|-可以使用(先垂直,然后水平)和(先水平,然后垂直)路径说明符连接各个节点-|。不清楚您希望如何处理这些连接的箭头,但这可以通过\draw命令选项轻松调整。

\documentclass[tikz]{standalone}
\usetikzlibrary{chains,scopes,calc}

\begin{document}
\begin{tikzpicture}[every node/.style={draw},every join/.style=->]
  \node (A) {A};
  {[start chain=B going below,every node/.append style=join]
    \node (B) [on chain,right=of A] {B};
    \node (b) [on chain] {b};
  }
  {[start chain=C going below,every node/.append style=join]
    \node (C) [on chain,right=of B] {C};
    \node (c) [on chain] {c\vphantom{b}};
  }
  \node (X) at ($($(B)!0.5!(C)$)!0.5!($(b)!0.5!(c)$)$) {X};
  \node (E) at ($($(B)!0.5!(C)$)-(0,2.5)$) {E};
  \draw [->] (A) |- (E);
  \draw (X) -| (c)
        (X) -| (b)
        (b) |- (E)
        (c) |- (E);
\end{tikzpicture}
\end{document}

在此处输入图片描述

答案2

我尝试使用以下代码重现您的图像:

\documentclass[border=5mm, tikz]{standalone}
\usetikzlibrary{arrows.meta,calc,chains,positioning}

\begin{document}
    \begin{tikzpicture}[
every node/.style = {draw, align=center},
     arrow/.style = -{Straight Barb[]},
      start chain = going right,
      node distance = 18mm and 9mm
                        ]
\node (A) [on chain] {A};
\node (B) [on chain] {B};
\node (C) [on chain] {C};
%
\node (b) [below=of B] {b};
\node (c) [below=of C] {c};
%
    \coordinate[below=9mm of B]  (x');
\node (X) [at={($(x')!0.5!(x'-|C)$)}]   {X};
\node (E) [below=of X]                  {E};
%
\path[arrow]    (B)      edge (b)  (C) edge (c)
                (B |- X) edge (X)  (C |- X) edge (X)
                (b)      edge (b |- E);
\draw[arrow]    (A) |- (E);   
\draw[arrow]    (c) |- (E);
    \end{tikzpicture}
\end{document}

在此处输入图片描述

如您所见,在代码中我没有使用包join中的宏chains。相反,我更愿意显式地绘制节点之间的路径,因为这样要求不高,使用的代码更少,并且代码结构清晰(与宏一样join)。

链上只有第一行节点(ABC),其他节点相对于其上方的节点定位。节点 X 是个例外,我为其定义了辅助坐标 c'

升级:如果你喜欢坚持使用宏join(不惜一切代价...:-)),看看下面的代码是否满足你的要求

\documentclass[border=5mm, many, tikz]{standalone}
\usetikzlibrary{arrows.meta,calc,chains,positioning}

\begin{document}
%---------------------------------------------------------------%
    \begin{tikzpicture}[
    every node/.style={draw, on chain},
          start chain=going below,
     arrow/.style = -{Straight Barb[]},
every join/.style = {arrow},
reset/.code={\def\tikz@after@path{}}
                        ]
\node (A) {A};
\node (B) [right=of A] {B};
\node (b) [join] {b};
%
\node (C) [right=of B] {C};
\node (c) [join] {c\vphantom{b}};
%
\node (X) [below=0.5 of $(B)!0.5!(C)$]  {X};
\node (E) [below=of X]                  {E};
%
\draw [arrow]   (A) |- (E);
\draw [arrow]   (X) -| (c)  (X) -| (b)
                (b) |- (E)  (c) |- (E);
    \end{tikzpicture}
\end{document}

它给:

在此处输入图片描述

代码源自 Paul Gessler 答案中的代码,但与之“非常显著”不同:

  • 节点“X”的位置定义更简单(如下图所示,节点“B”和“C”之间的中点)
  • 参数on chain是样式的一部分every node,因此不再需要在图片中定义它
  • join可以利用宏的节点已在本地添加了此选项

结果:简洁、干净的代码......

相关内容