我尝试在两个特定的节点锚点之间绘制一条非常粗的边。实际上,它们针对的是多部分节点的片段,但在本例中我将其保持简单。
\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
使用backgrounds
TikZ 库将边缘放入范围中。这样可以消除与节点重叠的部分。但它无法修复边缘太短而无法到达节点边界的间隙。
- 当边缘角度较大时,设置
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
另一个锚点。但可以使用相同的想法 - 只有from
和to
在这种情况下会有很大的不同。
基本语法如下:
\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 度以上的线条斜率来说已经足够了...可以使用基本几何形状进行简单计算 :-)
笔记: 此解决方案不适用于末端带有箭头的线,它们将被节点部分覆盖。在这种情况下,可以使用一种解决方案,即在两端之间的某处使用箭头装饰路径。