3

MWE:

\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}

Result:

figure 1

I wish that the curves following the figures, without getting the code to complicated, example:

figure 2

Also see my releated question, which continues this one.

Thank you for your help and effort in advance!

Su-47
  • 2,508

3 Answers3

7

Here's a method using the calc library, which is loaded at the beginning with \usetikzlibrary{calc}. Change the first arrow to:

\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);

And change the second arrow to:

\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);

I renamed the coordinates so the code remains readable. This is the result:

enter image description here

You can change the strength / direction of the in / out parts of the arrow with the +(direction:strength) method as I've done. The (a)!.5!(b) indicates the coordinate exactly halfway between the coordinates (a) and (b).


EDIT: This is more of a long comment to describe what is going on. Both arrows are paths through 3 points, but the middle point is described in two different ways. I cheated a little bit for the first one, so let me describe the second one first.

Second arrow: You gave an arrow going out of (current bounding box.south east) and going into (above output); these are the green circles. Renaming them as (c) and (d), respectively, the coordinate ($(c)!.5!(d)$) is exactly halfway between (c) and (d); this is the blue circle. Then, the coordinate ($($(c)!.5!(d)$)+(180:8.3)$) is 8.3 units (centimeters, I think) in the 180 direction out of ($(c)!.5!(d)$); this is the large red circle. Below, I've overlaid my suggested arrow with slight adjustments in the 8.3 parameter to show you how this part works.

enter image description here

% 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);
}

In my suggested arrow, there are four occurrences of +(angle:factor). The first one is out of the bottom green node, the second one is into the big red node, the third one is out of the big red node, the fourth one is into the top green node. This follows by using the code (node1) .. controls +(angle1:factor1) and +(angle2:factor2) .. (node2), which can be used as many times in sequence as desired, similar to the usual (node1) -- (node2) -- (node3), and so on.

First arrow: I should have done the same method as in the second arrow here, but I realized there is no need to define the middle coordinate of the arrow path in two steps. So I just defined the middle coordinate (the large red circle) as being exactly halfway between the start and end coordinates (the two green circles). The "halfway" notion is given by the .5 parameter, and below I've overlaid my suggested arrow with slights changes to this parameter.

enter image description here

% 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);
}

If this works for you, then great. But if you need to adjust the position of the middle (red) coordinate, in my method you can't adjust the horizontal position, which is why it may be better to use a 2-step process as in the second arrow above.

  • Hello @Jānis Lazovskis! Thank you for the answer! I tried to understand the +(angle:factor) statement for the first arrow. I painted an vector diagram and tried to follow in which direction the timing pointer shows, but I didn't get it. First 0° its clear, than 90° what isn't clear, than 270° and 180°, both is clear. Also the connection of two controls statements with the ($(coordinate)!.5!(coordinate)$) part isn't clear. I also red the section 13.5 Coordinate Calculations at pages 145-149 of the PGF manual, but its to complicated for me to understand it. Could you please explain it? – Su-47 Nov 26 '19 at 17:16
  • 1
    @Su-47 See my edit above. You should think of coordinates given by (a) or ($(a)!.5!(b)$) or ($($(a)!.5!(b)$)+(30:1)$) all in the same way - they are simply names for x,y positions in your drawing. The parenthetical dollar signs ($...$) indicate you are doing a calculation in between them to define a new position. I know the TikZ manual can be hard to grasp - but you're doing the right thing: try something, check the manual and this forum for existing solutions, ask if you can't resolve your problem. Let me know if things still aren't clear. – Jānis Lazovskis Nov 27 '19 at 09:59
  • Hello @Jānis Lazovskis! Thank you for this greate explanation! Now its all clear. I asked because I don't like to use something what I don't know how it work. An other thing. Can one use the syntax ($(coordinate)!.5!(coordinate)$) to solve this task? I guess no, but I think its a try worth. Anyway, thank you for taking time and effort! – Su-47 Nov 27 '19 at 12:24
  • @Su-47 Your linked question looks difficult - my initial thought is that since what you want to do is usually done with postaction=decorate, perhaps something with after creation needs to be done? But I don't know much about the datavisualization library, so this is only speculation. – Jānis Lazovskis Nov 27 '19 at 14:00
  • Hello @Jānis Lazovskis! Maybe its possible with postaction=decorate, but I don't know how to get the correct position for the arrow tips. That's why I'am asking. Any Idea? – Su-47 Nov 27 '19 at 17:04
  • @Su-47 I'll answer on the other thread. – Jānis Lazovskis Nov 27 '19 at 17:42
3

Here is yet another option using the in and out keys. The first curve can be drawn with

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

and the second one with

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

where we built in the horizontal position of controller to make sure the path wraps around that node.

enter image description here

\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}
2

Would something like this work?

\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}

to get:

enter image description here