在 TikZ 中使用相对坐标绘制连接曲线

在 TikZ 中使用相对坐标绘制连接曲线

我想在 TikZ 中绘制下图:

tikz 图

目前我使用以下代码来执行此操作:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{snakes,arrows,shapes}

\begin{document}

\begin{tikzpicture}[>=latex',node distance = 2cm]
 \node (S1) {$S_1$};
 \node [left of = S1] (S2) {$S_2$};
 \node [above of = S2,node distance=1.04cm] (A) {$A$}; 
 \node [above of = S1,node distance=1.04cm] (B) {$B$};

 \node [below of = S2,node distance=1.04cm] (C) {$C$};
 \node [below of = S1,node distance=1.04cm] (D) {$D$};

 \draw [->,thick] (S1) to[bend left=40] node {} (S2);
 \draw [->,thick] (S2) to[bend left=40] node {} (S1);

 \draw [->,thick] (A) to[bend right=40] node {} (B);
 \draw [->,thick] (D) to[bend right=40] node {} (C);

\end{tikzpicture}

\end{document}

但是您会注意到,我使用绝对距离(1.04 厘米)来确保曲线在中点相交。如果我更改节点距离,则每次都必须通过反复试验手动调整绝对距离。有没有办法使用 TikZ 绘制这样的图表而不使用绝对距离,以便当我更改节点距离时曲线会自动调整?

答案1

您可以尝试以下方法。尽管它也使用了一些魔法常数,但只要算出来一次(好吧,我帮您算出来了 :)),您就不需要再修改它们了。\coeffx并且\coeffy已经为您优雅地设置好了,您可以根据需要进行\nodedistancex调整。\nodedistancey

\documentclass{minimal}

\usepackage{tikz}
\usetikzlibrary{arrows,positioning}

\def \coeffx{0.29}
\def \coeffy{0.91}
\def \nodedistancex{4cm}
\def \nodedistancey{1cm}
\def \offsetx{\nodedistancex*\coeffx}
\def \offsety{\nodedistancey*\coeffy}

\begin{document}

\begin{tikzpicture}[>=latex', node distance=\nodedistancey and \nodedistancex]
 \node (S1) {$S_1$};
 \node[left=of S1] (S2) {$S_2$};
 \node[above=of S2] (A) {$A$}; 
 \node[above=of S1] (B) {$B$};
 \node[below=of S2] (C) {$C$};
 \node[below=of S1] (D) {$D$};

 \draw[->,thick] (S1) .. controls +(-\offsetx,\offsety) and +(\offsetx,\offsety) .. (S2);
 \draw[->,thick] (S2) .. controls +(\offsetx,-\offsety) and +(-\offsetx,-\offsety) .. (S1);
 \draw[->,thick] (A) .. controls +(\offsetx,-\offsety) and +(-\offsetx,-\offsety) .. (B);
 \draw[->,thick] (D) .. controls +(-\offsetx,\offsety) and +(\offsetx,\offsety) .. (C);
\end{tikzpicture}

\end{document}

在此处输入图片描述在此处输入图片描述

答案2

一个解决方案如下。我故意在图中增加了行,以便您可以看到循环的一个好处。输出为

图表

代码是(我希望它是不言自明的):

\documentclass{minimal}

\usepackage{tikz}
\usetikzlibrary{matrix}
\usetikzlibrary{calc}

\begin{document}


\begin{tikzpicture}[>=latex']

\pgfmathsetmacro{\rows}{5}

\matrix[matrix of math nodes,column sep=2cm,row sep = 1cm] (m) {
A&B\\
S_2&S_1\\
C&D\\
S_4&S_3\\
E&F\\
};

\foreach \k in {1,...,\rows}{
    \coordinate (c\k) at ($(m-\k-1)!0.5!(m-\k-2)$);
}

\foreach \k [count=\kprev] in {2,...,\rows}{

    \ifodd \k
        \tikzset{dir/.style={<-}}
    \else
        \tikzset{dir/.style={->}}
    \fi

    \coordinate (c) at ($(c\kprev)!0.5!(c\k)$);
    \draw[dir] (m-\kprev-1) to[out=-45,in=180] (c) to[out=0,in=225] (m-\kprev-2);
    \draw[dir] (m-\k-1) to[out=45,in=180] (c) to[out=0,in=135] (m-\k-2);
}   

\end{tikzpicture}

\end{document}

编辑:修复代码以纠正箭头

答案3

您可以在 A 和 S1 之间的路径中间添加一个点,然后以该点为起点画出两条弧

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{snakes,arrows,shapes}

\begin{document}

\begin{tikzpicture}[>=latex',node distance = 2cm]
 \node (S1) {$S_1$};
 \node [left of = S1] (S2) {$S_2$};
 \node [above of = S2,node distance=1.5cm] (A) {$A$}; 
 \node [above of = S1,node distance=1.5cm] (B) {$B$};

 \node [below of = S2,node distance=1.3cm] (C) {$C$};
 \node [below of = S1,node distance=1.3cm] (D) {$D$};

\path(A) -- (S1)coordinate[pos=0.5](inter1);
\path(C) -- (S1)coordinate[pos=0.5](inter2);
 \draw [->,thick] (S1) to[out=135,in=0] (inter1) to [out=180,in=45] (S2);
 \draw [->,thick] (S2) to[out=-45,in=180] (inter2) to [out=0,in=-135] (S1);
 \draw [->,thick] (A) to[out=-45,in=180] (inter1) to [out=0,in=-135]  (B);
 \draw [->,thick] (D)  to[out=135,in=0] (inter2) to [out=180,in=45] (C);

\end{tikzpicture}

\end{document}

弧

相关内容