如何弯曲 TikZ 图形周围的曲线?

如何弯曲 TikZ 图形周围的曲线?

梅威瑟:

\documentclass{scrartcl}
\usepackage{tikz}
\usetikzlibrary{positioning}
\tikzset{
         signal/.style = coordinate,
         sum/.style = {
                       draw,
                       circle,
                       minimum size = 2mm
                      },
         block/.style = {
                         draw,
                         rectangle,
                         minimum height = 2em,
                         minimum width = 4em
                        },
         branch/.style = {
                          sum,
                          minimum size = 1mm,
                          fill = black
                         }
        }

\begin{document}

  \begin{tikzpicture}[auto]

    %placing the nodes
    \node[signal] (input) {};
    \node[sum, right = of input] (left sum) {};
    \node[block, right = of left sum] (controller) {$G_R$};
    \node[block, right = of controller] (system) {$G_S$};
    %connecting the controller and system to get the coordinates of u, its needed for the placement of the measurement block
    \draw
      [->] (controller) -- node[name = u] {$U$} (system);
    \node[block, above = of system] (dynamic of disturbances) {$G_D$};
    \node[signal, left = of dynamic of disturbances] (disturbances) {};
    \node[sum, right = of system] (right sum) {};
    \node[branch, right = of right sum] (branch) {};
    \node[signal, right = of branch] (output) {};
    \node[sum, below = of branch] (lower sum) {};
    \node[signal, right = of lower sum] (measurement noise) {};
    \node[block] (measurement) at (u |- lower sum) {$G_M$};
    %connecting the nodes
    \draw
      [->] (input) -- node {$W$} (left sum);
    \draw
      [->] (left sum) -- node {$E$} (controller);
    \draw
      [->] (system) -- (right sum);
    \draw
      [->] (disturbances) -- node {$Z$} (dynamic of disturbances);
    \draw
      [->] (dynamic of disturbances) -| (right sum);
    \draw
      (right sum) -- (branch);
    \draw
      [->] (branch) -- node {$Y$} (output);
    \draw
      [->] (branch) -- (lower sum);
    \draw
      [->] (measurement noise) -- node[above] {$M$} (lower sum);
    \draw
      [->] (lower sum) -- (measurement);
    \draw
      [->] (measurement) -| node[pos = .95] {$-$} (left sum);
    %path from Z to Y
    \node[above of = dynamic of disturbances] (above G_D) {};
    \node[right of = above G_D] (corner above right sum) {};
    \node[above of = branch] (above branch) {};
    \node[above of = output] (above output) {};
    \draw
      [->] (above G_D) .. controls (corner above right sum) and (above branch) .. (above output);

  \end{tikzpicture}

  \[G_Z=\ldots\]

  \begin{tikzpicture}[auto]

    %placing the nodes
    \node[signal] (input) {};
    \node[sum, right = of input] (left sum) {};
    \node[block, right = of left sum] (controller) {$G_R$};
    \node[block, right = of controller] (system) {$G_S$};
    %connecting the controller and system, see above
    \draw
      [->] (controller) -- node[name = u] {$U$} (system);
    \node[block, above = of system] (dynamic of disturbances) {$G_D$};
    \node[signal, left = of dynamic of disturbances] (disturbances) {};
    \node[sum, right = of system] (right sum) {};
    \node[branch, right = of right sum] (branch) {};
    \node[signal, right = of branch] (output) {};
    \node[sum, below = of branch] (lower sum) {};
    \node[signal, right = of lower sum] (measurement noise) {};
    \node[block] (measurement) at (u |- lower sum) {$G_M$};
    %connecting the nodes
    \draw
      [->] (input) -- node {$W$} (left sum);
    \draw
      [->] (left sum) -- node {$E$} (controller);
    \draw
      [->] (system) -- (right sum);
    \draw
      [->] (disturbances) -- node {$Z$} (dynamic of disturbances);
    \draw
      [->] (dynamic of disturbances) -| (right sum);
    \draw
      (right sum) -- (branch);
    \draw
      [->] (branch) -- node {$Y$} (output);
    \draw
      [->] (branch) -- (lower sum);
    \draw
      [->] (measurement noise) -- node[above] {$M$} (lower sum);
    \draw
      [->] (lower sum) -- (measurement);
    \draw
      [->] (measurement) -| node[pos = .95] {$-$} (left sum);
    %path from M to Y
    \node[below of = measurement noise] (below M) {};
    \node[below of = input] (below W) {};
    \node[above of = input] (above W) {};
    \node[above of = output] (above output) {};
    \draw
      [->] (current bounding box.south east) .. controls (current bounding box.south west) and (current bounding box.north west) .. (above output);

  \end{tikzpicture}

  \[G_M=\ldots\]

\end{document}

结果:

图1

我希望曲线遵循图形,而不必使代码太复杂,例如:

图 2

我的相关问题,延续了这个问题。

提前感谢您的帮助和努力!

答案1

以下是使用库的方法calc,该方法在开始时以 加载\usetikzlibrary{calc}。将第一个箭头更改为:

\coordinate (a) at (above G_D);
\coordinate (b) at (above output);
\draw [->] (a) .. controls +(0:2) and +(90:1) .. ($(a)!.5!(b)$) .. controls +(270:1) and +(180:2) .. (b);

并将第二个箭头更改为:

\coordinate (c) at (current bounding box.south east);
\coordinate (d) at (above output);
\draw [->] (c) .. controls +(180:8) and +(270:2) .. ($($(c)!.5!(d)$)+(180:8.3)$) .. controls +(90:2) and +(180:8) .. (d);

我重命名了坐标,以便代码仍然可读。结果如下:

在此处输入图片描述

+(direction:strength)您可以像我一样使用 方法来改变箭头的入/出部分的强度/方向。(a)!.5!(b)表示坐标恰好位于 和(a)的中间(b)


编辑:这更像是一个长注释,用来描述发生了什么。两个箭头都是通过 3 个点的路径,但中间点以两种不同的方式描述。我对第一个有点作弊,所以让我先描述第二个。

第二支箭:您给出了一个从 出发(current bounding box.south east)和进入 的箭头(above output);这些是绿色圆圈。将它们分别重命名为(c)(d),坐标($(c)!.5!(d)$)恰好位于(c)和 的中间(d);这是蓝色圆圈。然后,坐标($($(c)!.5!(d)$)+(180:8.3)$)以 为8.3单位(我认为是厘米)在180的方向上($(c)!.5!(d)$);这是大红色圆圈。下面,我在参数中略微调整了建议的箭头,8.3以向您展示此部分的工作原理。

在此处输入图片描述

% Suggested arrow
\coordinate (c) at (current bounding box.south east);
\coordinate (d) at (above output);
\draw[->] (c) .. controls +(180:8) and +(270:2) .. ($($(c)!.5!(d)$)+(180:8.3)$) .. controls +(90:2) and +(180:8) .. (d);
% Large colored circles
\fill[green] (c) circle (.1); 
\fill[green] (d) circle (.1);
\fill[blue] ($(c)!.5!(d)$) circle (.1);
\fill[red] ($($(c)!.5!(d)$)+(180:8.3)$) circle (.1);
% Shifted arrows
\foreach \pos in {7.7,8,8.3,8.6,8.9}{
  \draw[->,opacity=.3] (c) .. controls +(180:8) and +(270:2) .. ($($(c)!.5!(d)$)+(180:\pos)$) .. controls +(90:2) and +(180:8) .. (d);
  \fill[red,opacity=.3] ($($(c)!.5!(d)$)+(180:\pos)$) circle (.05);
  \draw[->,red,opacity=.3]  ($($(c)!.5!(d)$)+(180:\pos)$) -- +(90:2);
  \draw[->,red,opacity=.3]  ($($(c)!.5!(d)$)+(180:\pos)$) -- +(270:2);
}

在我建议的箭头中,出现了四次+(angle:factor)。第一个是在......之外底部的绿色节点,第二个是进入大红色节点,第三个是在......之外大红色节点,第四个是进入顶部绿色节点。接下来使用代码(node1) .. controls +(angle1:factor1) and +(angle2:factor2) .. (node2),可以按顺序多次使用,类似于通常的(node1) -- (node2) -- (node3),依此类推。

第一箭:我应该使用与此处第二个箭头相同的方法,但我意识到没有必要分两步定义箭头路径的中间坐标。所以我只是将中间坐标(大红色圆圈)定义为起始和结束坐标(两个绿色圆圈)的中间位置。“中间”概念由参数给出.5,下面我将我建议的箭头与此参数的细微变化叠加在一起。

在此处输入图片描述

% Suggested arrow
\coordinate (a) at (above G_D);
\coordinate (b) at (above output);
\draw[->] (a) .. controls +(0:2) and +(90:1) .. ($(a)!.5!(b)$) .. controls +(270:1) and +(180:2) .. (b);
% Large colored circles
\fill[green] (a) circle (.1); 
\fill[green] (b) circle (.1);
\fill[red] ($(a)!.5!(b)$) circle (.1);
% Shifted arrows
\foreach \pos in {.3,.4,.5,.6,.7}{
  \draw[->,opacity=.3] (a) .. controls +(0:2) and +(90:1) .. ($(a)!\pos!(b)$) .. controls +(270:1) and +(180:2) .. (b);
  \fill[red,opacity=.3] ($(a)!\pos!(b)$) circle (.05);
  \draw[->,red,opacity=.3] ($(a)!\pos!(b)$) -- +(90:1);
  \draw[->,red,opacity=.3] ($(a)!\pos!(b)$) -- +(270:1);
}

如果这对您有用,那就太好了。但如果您需要调整中间(红色)坐标的位置,按照我的方法,您无法调整水平位置,这就是为什么最好使用上面第二个箭头所示的两步流程。

答案2

in这是使用和键的另一个选项out。第一条曲线可以用

\draw[->] (above G_D) to[out=0,in=180,looseness=2] (above output);

第二个是

\draw[->] (current bounding box.south east) -- 
  (controller|-current bounding box.south)
  to[out=180,in=180,looseness=1.5] (controller|-above output)
  -- (above output);

我们在水平位置构建controller以确保路径围绕该节点。

在此处输入图片描述

\documentclass{scrartcl}
\usepackage{tikz}
\usetikzlibrary{
                arrows.meta,
                bending,
                positioning
               }
\tikzset{
         > = Latex,
         arrows = {[bend]},
         signal/.style = coordinate,
         sum/.style = {
                       draw,
                       circle,
                       minimum size = 2mm
                      },
         block/.style = {
                         draw,
                         rectangle,
                         minimum height = 2em,
                         minimum width = 4em
                        },
         branch/.style = {
                          sum,
                          minimum size = 1mm,
                          fill = black
                         }
        }

\begin{document}

  \begin{tikzpicture}[auto]

    %placing the nodes
    \node[signal] (input) {};
    \node[sum, right = of input] (left sum) {};
    \node[block, right = of left sum] (controller) {$G_R$};
    \node[block, right = of controller] (system) {$G_S$};
    %connecting the controller and system to get the coordinates of u, its needed for the placement of the measurement block
    \draw
      [->] (controller) -- node[name = u] {$U$} (system);
    \node[block, above = of system] (dynamic of disturbances) {$G_D$};
    \node[signal, left = of dynamic of disturbances] (disturbances) {};
    \node[sum, right = of system] (right sum) {};
    \node[branch, right = of right sum] (branch) {};
    \node[signal, right = of branch] (output) {};
    \node[sum, below = of branch] (lower sum) {};
    \node[signal, right = of lower sum] (measurement noise) {};
    \node[block] (measurement) at (u |- lower sum) {$G_M$};
    %connecting the nodes
    \draw
      [->] (input) -- node {$W$} (left sum);
    \draw
      [->] (left sum) -- node {$E$} (controller);
    \draw
      [->] (system) -- (right sum);
    \draw
      [->] (disturbances) -- node {$Z$} (dynamic of disturbances);
    \draw
      [->] (dynamic of disturbances) -| (right sum);
    \draw
      (right sum) -- (branch);
    \draw
      [->] (branch) -- node {$Y$} (output);
    \draw
      [->] (branch) -- (lower sum);
    \draw
      [->] (measurement noise) -- node[above] {$M$} (lower sum);
    \draw
      [->] (lower sum) -- (measurement);
    \draw
      [->] (measurement) -| node[pos = .95] {$-$} (left sum);
    %path from Z to Y
    \node[above of = dynamic of disturbances] (above G_D) {};
    \node[right of = above G_D] (corner above right sum) {};
    \node[above of = branch] (above branch) {};
    \node[above of = output] (above output) {};
     \draw
       [->] (above G_D) to[out=0,in=180,looseness=2] (above output);

  \end{tikzpicture}

  \[G_Z=\ldots\]

  \begin{tikzpicture}[auto]

    %placing the nodes
    \node[signal] (input) {};
    \node[sum, right = of input] (left sum) {};
    \node[block, right = of left sum] (controller) {$G_R$};
    \node[block, right = of controller] (system) {$G_S$};
    %connecting the controller and system, see above
    \draw
      [->] (controller) -- node[name = u] {$U$} (system);
    \node[block, above = of system] (dynamic of disturbances) {$G_D$};
    \node[signal, left = of dynamic of disturbances] (disturbances) {};
    \node[sum, right = of system] (right sum) {};
    \node[branch, right = of right sum] (branch) {};
    \node[signal, right = of branch] (output) {};
    \node[sum, below = of branch] (lower sum) {};
    \node[signal, right = of lower sum] (measurement noise) {};
    \node[block] (measurement) at (u |- lower sum) {$G_M$};
    %connecting the nodes
    \draw
      [->] (input) -- node {$W$} (left sum);
    \draw
      [->] (left sum) -- node {$E$} (controller);
    \draw
      [->] (system) -- (right sum);
    \draw
      [->] (disturbances) -- node {$Z$} (dynamic of disturbances);
    \draw
      [->] (dynamic of disturbances) -| (right sum);
    \draw
      (right sum) -- (branch);
    \draw
      [->] (branch) -- node {$Y$} (output);
    \draw
      [->] (branch) -- (lower sum);
    \draw
      [->] (measurement noise) -- node[above] {$M$} (lower sum);
    \draw
      [->] (lower sum) -- (measurement);
    \draw
      [->] (measurement) -| node[pos = .95] {$-$} (left sum);
    %path from M to Y
    \node[below of = measurement noise] (below M) {};
    \node[below of = input] (below W) {};
    \node[above of = input] (above W) {};
    \node[above of = output] (above output) {};
    \draw
      [->] (current bounding box.south east) -- 
      (controller|-current bounding box.south)
      to[out=180,in=180,looseness=1.5] (controller|-above output)
      -- (above output);

  \end{tikzpicture}

  \[G_M=\ldots\]

\end{document}

答案3

这样的事情会起作用吗?

\documentclass{scrartcl}
\usepackage{tikz}
\usetikzlibrary{
                arrows.meta,
                bending,
                positioning
               }
\tikzset{
         > = Latex,
         arrows = {[bend]},
         signal/.style = coordinate,
         sum/.style = {
                       draw,
                       circle,
                       minimum size = 2mm
                      },
         block/.style = {
                         draw,
                         rectangle,
                         minimum height = 2em,
                         minimum width = 4em
                        },
         branch/.style = {
                          sum,
                          minimum size = 1mm,
                          fill = black
                         }
        }

\begin{document}

  \begin{tikzpicture}[auto]

    %placing the nodes
    \node[signal] (input) {};
    \node[sum, right = of input] (left sum) {};
    \node[block, right = of left sum] (controller) {$G_R$};
    \node[block, right = of controller] (system) {$G_S$};
    %connecting the controller and system to get the coordinates of u, its needed for the placement of the measurement block
    \draw
      [->] (controller) -- node[name = u] {$U$} (system);
    \node[block, above = of system] (dynamic of disturbances) {$G_D$};
    \node[signal, left = of dynamic of disturbances] (disturbances) {};
    \node[sum, right = of system] (right sum) {};
    \node[branch, right = of right sum] (branch) {};
    \node[signal, right = of branch] (output) {};
    \node[sum, below = of branch] (lower sum) {};
    \node[signal, right = of lower sum] (measurement noise) {};
    \node[block] (measurement) at (u |- lower sum) {$G_M$};
    %connecting the nodes
    \draw
      [->] (input) -- node {$W$} (left sum);
    \draw
      [->] (left sum) -- node {$E$} (controller);
    \draw
      [->] (system) -- (right sum);
    \draw
      [->] (disturbances) -- node {$Z$} (dynamic of disturbances);
    \draw
      [->] (dynamic of disturbances) -| (right sum);
    \draw
      (right sum) -- (branch);
    \draw
      [->] (branch) -- node {$Y$} (output);
    \draw
      [->] (branch) -- (lower sum);
    \draw
      [->] (measurement noise) -- node[above] {$M$} (lower sum);
    \draw
      [->] (lower sum) -- (measurement);
    \draw
      [->] (measurement) -| node[pos = .95] {$-$} (left sum);
    %path from Z to Y
    \node[above of = dynamic of disturbances] (above G_D) {};
    \node[right  = 2.2cm of above G_D] (corner above right sum) {};
    \node[below  = 1.5cm of corner above right sum] (above branch) {};
    \node[above of = output] (above output) {};
    % more info see here: https://tex.stackexchange.com/questions/33607/easy-curves-in-tikz
    \draw [->, red, thick] plot [smooth, tension = 0.25] coordinates{ (above G_D.center)  (corner above right sum.center)  (above branch.center)  (above output.center)};
%      \draw [red] plot [smooth cycle]  (above G_D) -- (corner above right sum) -- (above  branch);

  \end{tikzpicture}



\end{document}

要得到:

在此处输入图片描述

相关内容