编辑

编辑

我尝试在两个特定的节点锚点之间绘制一条非常粗的边。实际上,它们针对的是多部分节点的片段,但在本例中我将其保持简单。

\documentclass[tikz]{standalone}
\usetikzlibrary{positioning}

\begin{document}
\begin{tikzpicture}[every node/.style={draw}]
  \node (A) {A};
  \node[below right=1 and 2 of A] (B) {B};
  \draw[line width=7] (A.east) to (B.west);
\end{tikzpicture}
\end{document}

这会导致边缘与节点相接处出现难看的间隙。

差距

我知道我可以on background layer使用backgroundsTikZ 库将边缘放入范围中。这样可以消除与节点重叠的部分。但它无法修复边缘太短而无法到达节点边界的间隙。

  • 当边缘角度较大时,设置line cap=rect不足以将其关闭。
  • 拉长边缘可能会使其从节点的另一侧弹出。

如何才能实现边缘和节点之间的无缝连接,看起来有点像下面的图片?

在此处输入图片描述

答案1

我倾向于简单地填充一条路径而不是画一条线:

  \fill (A.east) +(0,3.5pt) -- ([yshift=3.5pt]B.west) -- +(0,-7pt) -- ([yshift=-3.5pt]A.east) -- cycle;

填充路径假线

这会留下一个令人讨厌的,虽然很小,但在“线”和节点 A 的边界之间可见的间隙。为了避免这种情况,还要绘制填充区域:

\filldraw (A.east) +(0,3.5pt) -- ([yshift=3.5pt]B.west) -- +(0,-7pt) -- ([yshift=-3.5pt]A.east) -- cycle;

填充绘制假线

完整代码:

\documentclass[tikz,border=20pt]{standalone}
\usetikzlibrary{positioning}

\begin{document}
\begin{tikzpicture}
  [every node/.style={draw}]
  \node (A) {A};
  \node [below right=1 and 2 of A] (B) {B};
  \filldraw (A.east) +(0,3.5pt) -- ([yshift=3.5pt]B.west) -- +(0,-7pt) -- ([yshift=-3.5pt]A.east) -- cycle;
\end{tikzpicture}
\end{document}

编辑

为了方便起见,您可以定义一个pic来自动处理其中的一些问题。下面定义了两个这样的:lr connection用于从左到右(ish)连接和tb connection用于从上到下(ish)连接。显然,您必须做更多的工作才能启用“混合”模式的选项,例如从一个.north锚点到.east另一个锚点。但可以使用相同的想法 - 只有fromto在这种情况下会有很大的不同。

基本语法如下:

\pic [lr connect={from=<point to connect from>, to=<point to connect to>, line width=<connector width>}, <other tikz options>] {lr connection};

用于左右连接和

\pic [tb connect={from=<point to connect from>, to=<point to connect to>, line width=<connector width>}, <other tikz options>] {tb connection};

用于顶部-底部连接。

这是一个非常丑陋的可能输出示例:

丑陋的演示

\begin{tikzpicture}
  [every node/.style={draw}]
  \node (A) {A};
  \node [below right=1 and 2 of A] (B) {B};
  \pic [lr connect={from=A.east, to=B.west, line width=7pt}] {lr connection};
  \pic [lr connect={from=B.east, to={4,0}}] {lr connection};
  \node (C) at (6,-1) {C};
  \pic [lr connect={from={4,0}, to=C.west}, blue] {lr connection};
  \pic [lr connect={from=C.west, to=B.east, line width=5pt}, green] {lr connection};
  \node (D) [below left=of B -| C] {D};
  \node (E) [below left=of B] {E};
  \pic [tb connect={from=C.south, to=D.north, line width=7pt}, red] {tb connection};
  \pic [tb connect={from=E.north, to=A.south, line width=6pt}, orange] {tb connection};
  \pic [lr connect={from=D.west, to=E.east, line width=10pt}, magenta] {lr connection};
\end{tikzpicture}

编辑2

您可以定义命令\lrconnect[<optional arguments for tikz>]{<connection options>}\tbconnect[<tikz options>]{<connection options>}获得更多便利。

然后可以将同样丑陋的输出指定为

\begin{tikzpicture}
  [every node/.style={draw}]
  \node (A) {A};
  \node [below right=1 and 2 of A] (B) {B};
  \lrconnect{from=A.east, to=B.west, line width=7pt};
  \lrconnect{from=B.east, to={4,0}};
  \node (C) at (6,-1) {C};
  \lrconnect[blue]{from={4,0}, to=C.west};
  \lrconnect[green]{from=C.west, to=B.east, line width=5pt};
  \node (D) [below left=of B -| C] {D};
  \node (E) [below left=of B] {E};
  \tbconnect[red]{from=C.south, to=D.north, line width=7pt};
  \tbconnect[orange]{from=E.north, to=A.south, line width=6pt};
  \lrconnect[magenta]{from=D.west, to=E.east, line width=10pt};
\end{tikzpicture}

然而,这也提供了一些更有趣的可能性。例如:

更精美的东西

可以使用类似的东西来制作

\begin{tikzpicture}
  [
    every node/.style={fill=blue!75, text=white, font=\bfseries},
    tb connect={line width=7pt},
    lr connect={line width=7pt},
    draw=blue!25,
  ]
  \node (A) {A};
  \node [below right=1 and 2 of A] (B) {B};
  \node (C) at (6,-1) {C};
  \node (D) [below left=of B -| C] {D};
  \node (E) [below left=of B] {E};
  \foreach \i/\j in {A.east/B.west,C.west/B.east,D.west/E.east}
  {
    \lrconnect[left color=blue, right color=green]{from=\i,to=\j};
    \foreach \k in {.9,.8,...,.1}
    \lrconnect[fill=white, fill opacity=.75-.75*\k, draw=none]{from=\i,to=\j,line width=\k*7pt};
  }
  \foreach \i/\j in {C.south/D.north,E.north/A.south}
  {
    \tbconnect[left color=blue, right color=magenta]{from=\i,to=\j};
    \foreach \k in {.9,.8,...,.1}
    \tbconnect[fill=white, fill opacity=.75-.75*\k, draw=none]{from=\i,to=\j,line width=\k*7pt};
  }
\end{tikzpicture}

完整代码

\documentclass[tikz,border=20pt,multi]{standalone}
\usetikzlibrary{positioning}
\tikzset{
  lr connection/.pic={
    \filldraw [pic actions] (\myconnectfrom) +(0,.5*\myconnectwidth) -- ([yshift=.5*\myconnectwidth]\myconnectto) -- +(0,-\myconnectwidth) -- ([yshift=-.5*\myconnectwidth]\myconnectfrom) -- cycle;
  },
  lr connect/.code={
    \tikzset{
      lr connections/.cd,
      #1
    },
  },
  lr connections/.cd,
  from/.store in=\myconnectfrom,
  to/.store in=\myconnectto,
  line width/.store in=\myconnectwidth,
  from={0,0},
  to={0,0},
  line width=.4pt,
  /tikz/.cd,
  tb connection/.pic={
    \filldraw [pic actions] (\myconnectfrom) +(.5*\myconnectwidth,0) -- ([xshift=.5*\myconnectwidth]\myconnectto) -- +(-\myconnectwidth,0) -- ([xshift=-.5*\myconnectwidth]\myconnectfrom) -- cycle;
  },
  tb connect/.code={
    \tikzset{
      tb connections/.cd,
      #1
    },
  },
  tb connections/.cd,
  from/.store in=\myconnectfrom,
  to/.store in=\myconnectto,
  line width/.store in=\myconnectwidth,
  from={0,0},
  to={0,0},
  line width=.4pt,
}
\newcommand*\lrconnect[2][]{%
   \pic [lr connect={#2}, #1] {lr connection}}
\newcommand*\tbconnect[2][]{%
   \pic [tb connect={#2}, #1] {tb connection}}
\begin{document}
\begin{tikzpicture}
  [every node/.style={draw}]
  \node (A) {A};
  \node [below right=1 and 2 of A] (B) {B};
  \pic [lr connect={from=A.east, to=B.west, line width=7pt}] {lr connection};
  \pic [lr connect={from=B.east, to={4,0}}] {lr connection};
  \node (C) at (6,-1) {C};
  \pic [lr connect={from={4,0}, to=C.west}, blue] {lr connection};
  \pic [lr connect={from=C.west, to=B.east, line width=5pt}, green] {lr connection};
  \node (D) [below left=of B -| C] {D};
  \node (E) [below left=of B] {E};
  \pic [tb connect={from=C.south, to=D.north, line width=7pt}, red] {tb connection};
  \pic [tb connect={from=E.north, to=A.south, line width=6pt}, orange] {tb connection};
  \pic [lr connect={from=D.west, to=E.east, line width=10pt}, magenta] {lr connection};
\end{tikzpicture}
\begin{tikzpicture}
  [every node/.style={draw}]
  \node (A) {A};
  \node [below right=1 and 2 of A] (B) {B};
  \lrconnect{from=A.east, to=B.west, line width=7pt};
  \lrconnect{from=B.east, to={4,0}};
  \node (C) at (6,-1) {C};
  \lrconnect[blue]{from={4,0}, to=C.west};
  \lrconnect[green]{from=C.west, to=B.east, line width=5pt};
  \node (D) [below left=of B -| C] {D};
  \node (E) [below left=of B] {E};
  \tbconnect[red]{from=C.south, to=D.north, line width=7pt};
  \tbconnect[orange]{from=E.north, to=A.south, line width=6pt};
  \lrconnect[magenta]{from=D.west, to=E.east, line width=10pt};
\end{tikzpicture}
\begin{tikzpicture}
  [
    every node/.style={fill=blue!75, text=white, font=\bfseries},
    tb connect={line width=7pt},
    lr connect={line width=7pt},
    draw=blue!25,
  ]
  \node (A) {A};
  \node [below right=1 and 2 of A] (B) {B};
  \node (C) at (6,-1) {C};
  \node (D) [below left=of B -| C] {D};
  \node (E) [below left=of B] {E};
  \foreach \i/\j in {A.east/B.west,C.west/B.east,D.west/E.east}
  {
    \lrconnect[left color=blue, right color=green]{from=\i,to=\j};
    \foreach \k in {.9,.8,...,.1}
    \lrconnect[fill=white, fill opacity=.75-.75*\k, draw=none]{from=\i,to=\j,line width=\k*7pt};
  }
  \foreach \i/\j in {C.south/D.north,E.north/A.south}
  {
    \tbconnect[left color=blue, right color=magenta]{from=\i,to=\j};
    \foreach \k in {.9,.8,...,.1}
    \tbconnect[fill=white, fill opacity=.75-.75*\k, draw=none]{from=\i,to=\j,line width=\k*7pt};
  }
\end{tikzpicture}
\end{document}

答案2

是否要求线应位于(A.east)和之间B.west?查看\draw[...] (A.center) -- (B.center)背景层是否可以接受:

在此处输入图片描述

对于上图,您需要 TikZ 库backgrounds并定义节点填充:

\documentclass[border=3mm,
               tikz,
               preview
               ]{standalone}
\usetikzlibrary{backgrounds,positioning}

    \begin{document}
\begin{tikzpicture}[every node/.style={draw,fill=white}]
      \node (A) {A};
      \node[below right=1 and 2 of A] (B) {B};
    \scoped[on background layer]
\path   let \p1 = (A.center),
            \p2 = (B.center),
            \n1 = {veclen(\y2-\y1,\x2-\x1)} in
    (A.east) to node[sloped, fill=black,
                     minimum width=\n1, 
                     minimum height=3pt] {} 
    (B.west);
    \end{tikzpicture}
        \end{document}

编辑:正如您在评论中指出的那样(我之前在您的问题中忽略了这一点),您将用一些(多部分)节点替换该行。因此,我现在用宽度为 5pt 的空节点替换上一行,并fill=black通过该节点模拟上一行。您可以用您的真实节点替换此节点……但是,如果节点的最小高度更高,则它们的末端将不会被节点 A 和 B 切断……。

您可以看到,我计算了节点的最小宽度,即节点 A 和 B 中心之间的距离。如果此距离适合您的实际节点。它可能取决于节点高度。

这就是你要找的吗?

编辑(2): 我会再试一次猜测,问题是什么......所以另一个解决方案,考虑多部分节点(由分割矩形确定)并通过(非常粗?)线连接不同的部分:

在此处输入图片描述

该解决方案的代码相对简单:

\documentclass[border=3mm,
               tikz,
               preview
               ]{standalone}
\usetikzlibrary{backgrounds,positioning}

     \begin{document}
\begin{tikzpicture}[
    every node/.style={draw,fill=white},
    shorten <>/.style={shorten >=#1, shorten <=#1}]
  \node[rectangle split, rectangle split parts=3] (A) 
        {A1\nodepart{two}A2\nodepart{three}A3};
  \node[rectangle split, rectangle split parts=3,
        below right=1 and 2 of A] (B) 
        {B1\nodepart{two}B2\nodepart{three}B3};
\begin{scope}[on background layer]
\draw[line width=4pt,red!50,
      shorten <>=-4pt]   (A.one east) -- (B.three west);
\draw[line width=4pt,teal!50,
      shorten <>=-4pt]   (A.two east) -- (B.one west);
\end{scope}
\end{tikzpicture}
     \end{document}

我选择线条的延伸等于线条的宽度,这对于 45 度以上的线条斜率来说已经足够了...可以使用基本几何形状进行简单计算 :-)

笔记: 此解决方案不适用于末端带有箭头的线,它们将被节点部分覆盖。在这种情况下,可以使用一种解决方案,即在两端之间的某处使用箭头装饰路径。

相关内容