边缘匹配。我希望它们水平平行。我尝试更改 yshit 参数的值,但没有成功。
\documentclass{article}
\usepackage{geometry}
\usepackage{tikz}
\usetikzlibrary{automata, arrows.meta, positioning, shapes}
\begin{document}
\resizebox{0.9\textwidth}{!}{
\begin{tikzpicture}[
>={Stealth[round]},
line width=0.8pt,
state/.style={draw,rounded rectangle,line width=0.4pt},
]
\node [state] (q1){$\lbrace q_2,q_3,q_4,q_5,q_7,q_8,q_9 \rbrace$};
\node [state, right=2cm of q1] (q2){$\lbrace q_2,q_3,q_5,q_6,q_7 \rbrace$};
\path [->]
(q1) [transform canvas={yshift=4mm}, shorten <=-0.25pt, shorten >=-0.5pt] edge node [above, pos = 0.5] {$1$} (q2)
(q2) [transform canvas={yshift=-4mm}, shorten <=-0.25pt, shorten >=-0.5pt] edge node [below, pos = 0.5] {$0$} (q1);
\end{tikzpicture}
}
\end{document}
答案1
可能最好在 中执行tikz-cd
,但这里有一个intersection
解决方案。我使用边界上的角度。要使用(q1.4)
,还需要与第一个节点边界的交点。.4
yshift
\documentclass[tikz, border=1cm]{standalone}
\usetikzlibrary{arrows.meta, positioning, shapes, intersections}
\begin{document}
\begin{tikzpicture}[
>={Stealth[round]},
thick,
state/.style={draw, rounded rectangle, thin},
]
\node [state] (q1) {$\lbrace q_2,q_3,q_4,q_5,q_7,q_8,q_9 \rbrace$};
\node [state, right=2cm of q1, name path=q2] (q2) {$\lbrace q_2,q_3,q_5,q_6,q_7 \rbrace$};
\path[name path=aboveh] (q1.4) -| (q2);
\draw[->, name intersections={of=aboveh and q2}] (q1.4) --node[above] {$1$} (intersection-1);
\path[name path=belowh] (q1.-4) -| (q2);
\draw[<-, name intersections={of=belowh and q2}] (q1.-4) --node[below] {$2$} (intersection-1);
\end{tikzpicture}
\end{document}
编辑:
我现在发现shift left
只是tikz-cd
移动了箭头 - 所以它不再在边界上开始/结束。将工作相同。- 您可以像这样transform canvas={yshift=...}
给予\draw
(而不是给予)一个选项:edge
\draw[->, transform canvas={yshift=1mm}] (q1) --node[above]{$1$} (q2);
手动调整shorten
并不适用于所有节点大小。
答案2
该解决方案自动找到两个圆角矩形边界上的点,该点通过向左移动的线连接这些节点。
使用shift between rounded corners=<length>
带有可选值的键(默认值4pt
:)。
为了达到最佳效果,必须考虑以下几点
- 两个节点的形状都是圆角矩形
- 不能
<length>
太大,以便- 它可以至少有一个交点
- 它不应该找到一个以上的连接点
Everyrounded corners
存储了\radius
、\halfarcangle
以及\outer xsep
。我们可以使用 PGF 内部宏\pgf@sh@s@rounded rectangle
和来检索它们\pgf@sh@ma@<node name>
。
然后我们使用这些值再次绘制路径(\pgf@sh@bg@rounded rectangle
),但我们不使用完全相同的原始路径,而是使用边界外部的路径——就像我们在正常连接中使用的所有锚点一样。但是,由于我们不想找到中心和其他节点之间的边界点,因此我们需要自己找到这些交点。
代码
\documentclass[tikz]{standalone}
\usetikzlibrary{automata, arrows.meta, positioning, shapes.misc, intersections}
\makeatletter
\tikzset{
@insert rounded rectangle path/.code=% #1 = node name
\pgfsettransform{\csname pgf@sh@nt@#1\endcsname}%
\csname pgf@sh@s@rounded rectangle\endcsname
\csname pgf@sh@ma@#1\endcsname
\expandafter\def\expandafter\roundedrectanglepoints\expandafter{\roundedrectanglepoints
\pgfmathsetlengthmacro\radius{\radius+\outerxsep}%
\pgfmathsetlengthmacro\arcwidth{\arcwidth+\outerxsep}%
\pgfmathsetlengthmacro\halfheight{\halfheight+\outerysep}%
\pgfmathsetlengthmacro\halfwidth{\halfwidth+\outerxsep}%
\def\outerxsep{0pt}\def\outerysep{0pt}}%
\pgf@sh@savedpoints
\pgftransformshift{\pgfpointanchor{#1}{center}}%
\csname pgf@sh@bg@rounded rectangle\endcsname}
\makeatother
\tikzset{
shift between rounded corners/.default=4pt,
shift between rounded corners/.style={%
% this assumes both nodes to be rounded corners
% this assumes that \tikztostart and \tikztotarget
% are actually node names and no other coordinates
%
% #1 = shift to the left
% must be small enough so that the connection even hits the nodes
% with arc lengths > 180, more than one intersection
% exist which will lead to the wrong point to be found
/utils/exec={%
\pgfinterruptpath
\path[name path=@pathofstart,@insert rounded rectangle path=\tikztostart];
\path[name path=@pathoftarget,@insert rounded rectangle path=\tikztotarget];
\path[name path=@pathofstraight]\pgfextra
\pgfmathanglebetweenpoints{\pgfpointanchor{\tikztostart}{center}}{\pgfpointanchor{\tikztotarget}{center}}%
\pgftransformshift{\pgfpointanchor{\tikztostart}{center}}%
\pgftransformrotate{\pgfmathresult}%
\pgfpathmoveto{\pgfpoint{0}{#1}}%
\pgfpathlineto{\pgfpointadd{\pgfpointanchor{\tikztotarget}{center}}{\pgfpoint{0}{#1}}}%
\endpgfextra;
\tikzset{
name intersections={of=@pathofstart and @pathofstraight, by={@start}},
name intersections={of=@pathoftarget and @pathofstraight, by={@target}}}
\endpgfinterruptpath
},
to path={(@start) -- (@target) \tikztonodes}}}
\begin{document}
\begin{tikzpicture}[
>={Stealth[round]}, line width=0.8pt,
state/.style={draw, rounded rectangle, line width=0.4pt},
]
\node [state] (q1) {$\lbrace q_2,q_3,q_4,q_5,q_7,q_8,q_9 \rbrace$};
\node [state, right=2cm of q1] (q2) {$\lbrace q_2,q_3,q_5,q_6,q_7 \rbrace$};
\path [->]
(q1) edge[shift between rounded corners] node [above, pos = 0.5] {$1$} (q2)
(q2) edge[shift between rounded corners] node [below, pos = 0.5] {$0$} (q1);
\end{tikzpicture}
\begin{tikzpicture}[
>={Stealth[round]}, line width=0.8pt,
state/.style={draw, rounded rectangle, line width=0.4pt, rounded rectangle east arc=concave},
]
\node [state, rotate=-55] (q1) {$\lbrace q_2,q_3,q_4,q_5,q_7,q_8,q_9 \rbrace$};
\node [state, rotate=-80, below right=2cm of q1] (q2) {$\lbrace q_2,q_3,q_5,q_6,q_7 \rbrace$};
\path [->]
(q1) edge[shift between rounded corners] node [above, pos = 0.5] {$1$} (q2)
(q2) edge[shift between rounded corners] node [below, pos = 0.5] {$0$} (q1);
\end{tikzpicture}
\end{document}
输出
答案3
这是另一个基于交叉点的答案,与 hpekristiansen 的答案在精神上类似。用户级别的主要区别在于它允许您将偏移指定为距离,而不是使用节点上的角度锚。它还使用spath3
库来处理交叉点的东西。
它的工作原理是,首先在两个节点的中心之间绘制一条路径。然后,它将该路径平移所需的量。然后,它将平移后的路径与节点边界相交,并丢弃外部部分。最后,它渲染路径的剩余部分,以及任何额外的部分,例如箭头和节点。
这一切都很好地包装在了 中to path
。
\documentclass{article}
%\url{https://tex.stackexchange.com/q/654584/86}
\usepackage{geometry}
\usepackage{tikz}
\usetikzlibrary{
automata,
arrows.meta,
positioning,
shapes,
spath3,
intersections
}
\makeatletter
\tikzset{
every node/.style={
spath/save global=\tikz@fig@name
},
connect/.style={
to path={
\pgfextra{
\path[overlay,spath/save=connection path] (\tikztostart.center) -- (\tikztotarget.center);
\tikzset{
spath/transform={connection path}{yshift=#1},
spath/split at intersections with={connection path}{\tikztostart},
spath/split at intersections with={connection path}{\tikztotarget},
spath/remove components={connection path}{1,3},
}
} [spath/use=connection path] \tikztonodes
}
}
}
\makeatother
\begin{document}
\begin{tikzpicture}[
>={Stealth[round]},
line width=0.8pt,
state/.style={
draw,
rounded rectangle,
line width=0.4pt,
},
]
\node [state] (q1){\(\lbrace q_2,q_3,q_4,q_5,q_7,q_8,q_9 \rbrace\)};
\node [state, right=2cm of q1] (q2){\(\lbrace q_2,q_3,q_5,q_6,q_7 \rbrace\)};
\draw [->] (q1) to[connect=2mm] node [above, pos = 0.5] {\(1\)} (q2);
\draw [->] (q2) to[connect=-2mm] node [below, pos = 0.5] {\(0\)} (q1);
\end{tikzpicture}
\end{document}
(线条粗细的明显差异是由于我的 pdf 查看器造成的。)