使边平行

使边平行

边缘匹配。我希望它们水平平行。我尝试更改 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),还需要与第一个节点边界的交点。.4yshift

\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 查看器造成的。)

相关内容