在 TikZ 中一步步制作状态空间图动画的最佳方法

在 TikZ 中一步步制作状态空间图动画的最佳方法

介绍

很久以前,我开始学习如何使用 TikZ,并创建了一些做工不太好图表。其中一个图表是线性动力系统的状态空间表示。当我发现我可以用 TikZ 制作动画时,我尽力将该图表制作成动画,以解释应该一步一步思考如何绘制和理解该图表。

最近我用新学到的方法重新设计了一些旧图表,并决定制作一些动画,但我注意到我还应该修改如何为它们制作动画,因为它们与我制作的原始绘图不同。

问题

现在到了决策点。在创建节点然后创建它们之间的连接的图表中(下面的 MWE 2),最好的方法是逐步创建这些图表的动画吗?如何在已经读过 TikZ 图表后创建这样的分步动画?

我知道要求“最佳”有点主观和基于意见,但在这种情况下,我只是缺乏信息来决定如何进行,并且需要花费很长时间通过反复试验来了解哪种方法更合适。

“最佳”的标准。

  1. 在原始 TikZ 上绘制较少的改动
  2. 允许以(几乎)任何顺序逐步查看图表
  3. 编译速度快(或者不太长)

背景

我已经看到了使用、创建多页 pdf 和使用的一些可能性uncovermultido\animategraphics我不知道哪一个最适合我的需求。

据我所知,我猜测 uncover似乎更符合我的标准。

原始图表和动画 - MWE 1

这是我创建动画的第一种方法。它是笨拙,我曾经\ifthenelse定义过每个步骤中呈现的内容,代码很长,我不知道如何保留已经绘制的内容。真是一团糟。(我甚至不记得我在哪里找到了基于此代码的示例)。

MWE 1 如下:

\documentclass[border=5pt]{standalone}
\usepackage{amsmath,xifthen,tikz,animate}
\usetikzlibrary{calc}
\begin{document}
\begin{animateinline}[poster=last, controls]{1}
  \multiframe{8}{ii=0+1}{% ii=0,1,...99 ; rj=9.9,9.8,...,0.0
    \begin{tikzpicture}[very thick, every node/.style={font=\LARGE}];
      \definecolor{dkg}{rgb}{0,0.5,0};
      % ==========
      \useasboundingbox (-6,-3) rectangle ++(20,8);
      \node[blue, right] at (9.5,-0.5) {\Huge Step:\ii};

      \draw (2.5,0) rectangle ++(2,2) coordinate(G)  node[pos=0.5] {\Huge{$\int$}};

      \node at (-1,-1.5) {
        \begin{tabular}{l}
          $\dot{x} = A x + B u$ \\
          $y = C x + D u$
        \end{tabular}
      };

      \ifthenelse{\ii < 1}{
        \draw [-latex, teal] (G)++(0,-1) -- ++(1,0) coordinate(X) node[above]{$x$} -- ++(1,0);
      }{
        \ifthenelse{\ii < 2}{
          \draw [-latex, teal] (G)++(0,-1) -- ++(1,0) coordinate(X) node[above]{$x$} -- ++(1,0);
          \draw (1,1) coordinate(S) circle (1/2);
          \draw [-latex, orange] (S)++(1/2,0) -- ++(1,0) coordinate(E) node[midway, above]{$\dot{x}$};

        }{
          \ifthenelse{\ii < 3}{
            \draw [-latex, teal] (G)++(0,-1) -- ++(1,0) coordinate(X) node[above]{$x$} -- ++(1,0);
            \draw (1,1) coordinate(S) circle (1/2);
            \draw [-latex, orange] (S)++(1/2,0) -- ++(1,0) coordinate(E) node[midway, above]{$\dot{x}$};

            \draw (2.5,-2.5) coordinate(A) rectangle ++(2*1,2*1) node[pos=0.5]{$A$};
            \draw [-latex, teal] (X) -- ++(0,-2.5) -- ++(-1,0);

          }{
            \ifthenelse{\ii < 4}{
              \draw [-latex, teal] (G)++(0,-1) -- ++(1,0) coordinate(X) node[above]{$x$} -- ++(1,0);
              \draw (1,1) coordinate(S) circle (1/2);
              \draw [-latex, orange] (S)++(1/2,0) -- ++(1,0) coordinate(E) node[midway, above]{$\dot{x}$};

              \draw (2.5,-2.5) coordinate(A) rectangle ++(2*1,2*1) node[pos=0.5]{$A$};
              \draw [-latex, teal] (X) -- ++(0,-2.5) -- ++(-1,0);

              \draw [-latex, cyan] ($(A)+(0,1)$) -| ($(S)+(0,-0.5)$) node[below right]{$+$};
            }{
              \ifthenelse{\ii < 5}{
                \draw [-latex, teal] (G)++(0,-1) -- ++(1,0) coordinate(X) node[above]{$x$} -- ++(1,0);
                \draw (1,1) coordinate(S) circle (1/2);
                \draw [-latex, orange] (S)++(1/2,0) -- ++(1,0) coordinate(E) node[midway, above]{$\dot{x}$};

                \draw (2.5,-2.5) coordinate(A) rectangle ++(2*1,2*1) node[pos=0.5]{$A$};
                \draw [-latex, teal] (X) -- ++(0,-2.5) -- ++(-1,0);

                \draw [-latex, cyan] ($(A)+(0,1)$) -| ($(S)+(0,-0.5)$) node[below right]{$+$};

                \draw (-2.5,0) rectangle ++(2*1,2*1) coordinate(B) node[pos=0.5]{$B$};
                \draw [-latex, red] (B)++(0,-1) -- ++(1,0) node[above left]{$+$};
                \draw [-latex, dkg] (-4,1) coordinate(u) node[above]{$u$} |- ++(1.5,0);

              }{
                \ifthenelse{\ii < 6}{
                  \draw [-latex, teal] (G)++(0,-1) -- ++(1,0) coordinate(X) node[above]{$x$} -- ++(1,0);
                  \draw (1,1) coordinate(S) circle (1/2);
                  \draw [-latex, orange] (S)++(1/2,0) -- ++(1,0) coordinate(E) node[midway, above]{$\dot{x}$};

                  \draw (2.5,-2.5) coordinate(A) rectangle ++(2*1,2*1) node[pos=0.5]{$A$};
                  \draw [-latex, teal] (X) -- ++(0,-2.5) -- ++(-1,0);

                  \draw [-latex, cyan] ($(A)+(0,1)$) -| ($(S)+(0,-0.5)$) node[below right]{$+$};

                  \draw (-2.5,0) rectangle ++(2*1,2*1) coordinate(B) node[pos=0.5]{$B$};
                  \draw [-latex, red] (B)++(0,-1) -- ++(1,0) node[above left]{$+$};
                  \draw [-latex, dkg] (-4,1) coordinate(u) node[above]{$u$} |- ++(1.5,0);

                  \draw (6.5,0) coordinate(C) rectangle ++(2*1,2*1) node[pos=0.5]{$C$};
                  \draw (10.5,1) coordinate(y) circle (1/2);
                  \draw [-latex, violet] (y)++(0.5,0) -- ++(1,0) node[above]{$y$};
                  \draw [-latex, olive] ($(C)+(2*1,1)$) -- ($(y)+(-0.5,0)$) node[above left]{$+$};

                }{
                  \ifthenelse{\ii < 7}{
                    \draw [-latex, teal] (G)++(0,-1) -- ++(1,0) coordinate(X) node[above]{$x$} -- ++(1,0);
                    \draw (1,1) coordinate(S) circle (1/2);
                    \draw [-latex, orange] (S)++(1/2,0) -- ++(1,0) coordinate(E) node[midway, above]{$\dot{x}$};

                    \draw (2.5,-2.5) coordinate(A) rectangle ++(2*1,2*1) node[pos=0.5]{$A$};
                    \draw [-latex, teal] (X) -- ++(0,-2.5) -- ++(-1,0);

                    \draw [-latex, cyan] ($(A)+(0,1)$) -| ($(S)+(0,-0.5)$) node[below right]{$+$};

                    \draw (-2.5,0) rectangle ++(2*1,2*1) coordinate(B) node[pos=0.5]{$B$};
                    \draw [-latex, red] (B)++(0,-1) -- ++(1,0) node[above left]{$+$};
                    \draw [-latex, dkg] (-4,1) coordinate(u) node[above]{$u$} |- ++(1.5,0);

                    \draw (6.5,0) coordinate(C) rectangle ++(2*1,2*1) node[pos=0.5]{$C$};
                    \draw (10.5,1) coordinate(y) circle (1/2);
                    \draw [-latex, violet] (y)++(0.5,0) -- ++(1,0) node[above]{$y$};
                    \draw [-latex, olive] ($(C)+(2*1,1)$) -- ($(y)+(-0.5,0)$) node[above left]{$+$};

                    \draw (2.5,2.5) coordinate(D) rectangle ++(2*1,2*1) coordinate(B)  node[pos=0.5]{$D$};
                    \draw [-latex, dkg] ($(u)+(0.5*1,0)$) |- ($(D)+(0,1)$);
                    \draw [-latex, cyan] ($(D)+(2*1,1)$) -| ($(y)+(0,0.5)$) node[above right]{$+$};
                  }{
                    \draw [-latex, teal] (G)++(0,-1) -- ++(1,0) coordinate(X) node[above]{$x$} -- ++(1,0);
                    \draw (1,1) coordinate(S) circle (1/2);
                    \draw [-latex, orange] (S)++(1/2,0) -- ++(1,0) coordinate(E) node[midway, above]{$\dot{x}$};

                    \draw (2.5,-2.5) coordinate(A) rectangle ++(2*1,2*1) node[pos=0.5]{$A$};
                    \draw [-latex, teal] (X) -- ++(0,-2.5) -- ++(-1,0);

                    \draw [-latex, cyan] ($(A)+(0,1)$) -| ($(S)+(0,-0.5)$) node[below right]{$+$};

                    \draw (-2.5,0) rectangle ++(2*1,2*1) coordinate(B) node[pos=0.5]{$B$};
                    \draw [-latex, red] (B)++(0,-1) -- ++(1,0) node[above left]{$+$};
                    \draw [-latex, dkg] (-4,1) coordinate(u) node[above]{$u$} |- ++(1.5,0);

                    \draw (6.5,0) coordinate(C) rectangle ++(2*1,2*1) node[pos=0.5]{$C$};
                    \draw (10.5,1) coordinate(y) circle (1/2);
                    \draw [-latex, violet] (y)++(0.5,0) -- ++(1,0) node[above]{$y$};
                    \draw [-latex, olive] ($(C)+(2*1,1)$) -- ($(y)+(-0.5,0)$) node[above left]{$+$};

                    \draw (2.5,2.5) coordinate(D) rectangle ++(2*1,2*1) coordinate(B)  node[pos=0.5]{$D$};
                    \draw [-latex, dkg] ($(u)+(0.5*1,0)$) |- ($(D)+(0,1)$);
                    \draw [-latex, cyan] ($(D)+(2*1,1)$) -| ($(y)+(0,0.5)$) node[above right]{$+$};

                    \draw [very thick, red] (-3,-3) coordinate(eq) rectangle ++(12,8);
      }}}}}}}
    \end{tikzpicture}
  }
\end{animateinline}
\end{document}

结果如下。

在此处输入图片描述

新的动画图表 - MWE 2

这个新图表使用了一些个人本地定义的/.styles,组织得更好。首先定义节点,然后建立连接。代码很干净,易于更改,比旧代码好得多。但我不知道如何以最佳方式制作动画。

MWE 2 如下:

\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\tikzset{addCross/.style n args={6}{
    minimum size={#5 mm}, %minimum height=10mm,
    path picture={
      \draw[#6]
      (path picture bounding box.south east) -- (path picture bounding box.north west)
      (path picture bounding box.south west) -- (path picture bounding box.north east);
      \node at ($(path picture bounding box.south)!0.4!(path picture bounding box.center)$) {#1};
      \node at ($(path picture bounding box.west)!0.4!(path picture bounding box.center)$)  {#2};
      \node at ($(path picture bounding box.north)!0.4!(path picture bounding box.center)$) {#3};
      \node at ($(path picture bounding box.east)!0.4!(path picture bounding box.center)$)  {#4};
    }
  },
  addCross/.default={}{}{}{}{10}{}
}
\tikzset{mySimpleArrow/.style n args={2}{
    >={latex[#1]},
    every path/.style={draw=#2}
  },
  mySimpleArrow/.default={black}{black}
}
\tikzset{myBlockOpacity/.style n args={4}{
    every node/.style={rectangle,draw, text=black,
      minimum width=#1, minimum height=#2,
      fill opacity=#3, text opacity=#4}
  },
  myBlockOpacity/.default={1cm}{1cm}{0.4}{1}
}

\begin{document}
\begin{tikzpicture}[very thick]
  \begin{scope}
    \node[circle,draw,addCross={$+$}{$+$}{}{}{10}{black}] (N1) at (1,-0.5) {};
  \end{scope}

  \begin{scope}[shift={(3.0,-0.5)},myBlockOpacity]
    \node[fill=red] (A) at (0,-1.5) {$A$};
    \node[fill=green!50!black] (B) at (-4,0) {$B$};
    \node[fill=yellow!75!black] (C) at (3,0) {$C$};
    \node (I) at (0,0) {$\displaystyle \int$};
  \end{scope}
  
  \begin{scope}[mySimpleArrow={blue}{cyan}]
    \path[->] (-2.5,-0.5) node[above]{$u$} -- (B);
    \path[->] (B) -- (N1);
    \path[->] (N1) -- (I) node[midway, above] {$\dot{x}$};
    
    \path[->] (I) -- (4.5,-0.5) coordinate(x) node[above]{$x$} -- (C);
    \path[->] (x) |- (A) -| (N1);
    \path[->] (C) -- ++(1.5,0) node[above]{$y$};
  \end{scope}
\end{tikzpicture}
\end{document}

产生

在此处输入图片描述

答案1

定义了一个beamer类外命令,它指定要显示\uncover某个对象的帧号。tikzpicture

%\uncover{<current>}{<when>}{...<commands>...}
\newcommand\uncover[3]{\ifnum#1<#2\phantom{#3}\else#3\fi}

它依赖于\phantom{...}阻止对象被绘制的命令,但会评估坐标定义,甚至 TikZ 的自动边界框计算。这使我们能够引用隐藏对象的节点坐标,而无需对原始代码进行太多更改。

在此处输入图片描述

\documentclass[border=10pt]{standalone}
\usepackage{animate}
\usepackage{tikz}
\usetikzlibrary{calc}
\tikzset{addCross/.style n args={6}{
    minimum size={#5 mm}, %minimum height=10mm,
    path picture={
      \draw[#6]
      (path picture bounding box.south east) -- (path picture bounding box.north west)
      (path picture bounding box.south west) -- (path picture bounding box.north east);
      \node at ($(path picture bounding box.south)!0.4!(path picture bounding box.center)$) {#1};
      \node at ($(path picture bounding box.west)!0.4!(path picture bounding box.center)$)  {#2};
      \node at ($(path picture bounding box.north)!0.4!(path picture bounding box.center)$) {#3};
      \node at ($(path picture bounding box.east)!0.4!(path picture bounding box.center)$)  {#4};
    }
  },
  addCross/.default={}{}{}{}{10}{}
}
\tikzset{mySimpleArrow/.style n args={2}{
    >={latex[#1]},
    every path/.style={draw=#2}
  },
  mySimpleArrow/.default={black}{black}
}
\tikzset{myBlockOpacity/.style n args={4}{
    every node/.style={rectangle,draw, text=black,
      minimum width=#1, minimum height=#2,
      fill opacity=#3, text opacity=#4}
  },
  myBlockOpacity/.default={1cm}{1cm}{0.4}{1}
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%\uncover{<current>}{<when>}{...}
\newcommand\uncover[3]{\ifnum#1<#2\phantom{#3}\else#3\fi}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{document}
\begin{animateinline}[step,controls=step]{1}
\multiframe{13}{i=0+1}{  
  \begin{tikzpicture}[very thick]
    \begin{scope}
      \uncover{\i}{4}{\node[circle,draw,addCross={$+$}{$+$}{}{}{10}{black}] (N1) at (1,-0.5) {};}
    \end{scope}
  
    \begin{scope}[shift={(3.0,-0.5)},myBlockOpacity]
      \uncover{\i}{9}{\node[fill=red] (A) at (0,-1.5) {$A$};}
      \uncover{\i}{2}{\node[fill=green!50!black] (B) at (-4,0) {$B$};}
      \uncover{\i}{11}{\node[fill=yellow!75!black] (C) at (3,0) {$C$};}
      \uncover{\i}{6}{\node (I) at (0,0) {$\displaystyle \int$};}
    \end{scope}
    
    \begin{scope}[mySimpleArrow={blue}{cyan}]
      \uncover{\i}{1}{\path[->] (-2.5,-0.5) node[above]{$u$} -- (B);}
      \uncover{\i}{3}{\path[->] (B) -- (N1);}
      \uncover{\i}{5}{\path[->] (N1) -- (I) node[midway, above] {$\dot{x}$};}
      
      \uncover{\i}{7}{\path[->] (I) -- (4.5,-0.5) coordinate(x) node[above]{$x$} -- (C);}
      \uncover{\i}{8}{\path[->] (x) |- (A);}
      \uncover{\i}{10}{\path[->] (A) -| (N1);}
      \uncover{\i}{12}{\path[->] (C) -- ++(1.5,0) node[above]{$y$};}
    \end{scope}
  \end{tikzpicture}
}
\end{animateinline}
\end{document}

答案2

我不知道这对你来说是否理想。因为我更改了你的一些tikz代码,以便对每个路径使用绝对坐标。这样,每个单独的路径都可以在不参考其他路径中的坐标的情况下绘制。你可以自由决定将哪条路径包含在哪一帧中。使用路径\ifnum\i>'some frame number'前面的 来决定此路径是否将包含在下一帧中(某个帧号+1)。这是代码:

\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{animate}
\tikzset{addCross/.style n args={6}{
        minimum size={#5 mm}, %minimum height=10mm,
        path picture={
            \draw[#6]
            (path picture bounding box.south east) -- (path picture bounding box.north west)
            (path picture bounding box.south west) -- (path picture bounding box.north east);
            \node at ($(path picture bounding box.south)!0.4!(path picture bounding box.center)$) {#1};
            \node at ($(path picture bounding box.west)!0.4!(path picture bounding box.center)$)  {#2};
            \node at ($(path picture bounding box.north)!0.4!(path picture bounding box.center)$) {#3};
            \node at ($(path picture bounding box.east)!0.4!(path picture bounding box.center)$)  {#4};
        }
    },
    addCross/.default={}{}{}{}{10}{}
}
\tikzset{mySimpleArrow/.style n args={2}{
        >={latex[#1]},
        every path/.style={draw=#2}
    },
    mySimpleArrow/.default={black}{black}
}
\tikzset{myBlockOpacity/.style n args={4}{
        every node/.style={rectangle,draw, text=black,
            minimum width=#1, minimum height=#2,
            fill opacity=#3, text opacity=#4}
    },
    myBlockOpacity/.default={1cm}{1cm}{0.4}{1}
}

\begin{document}
\begin{animateinline}[autoplay,loop,poster=last, controls]{1}
\multiframe{13}{i=0+1}{
    \begin{tikzpicture}[line width=1pt]
        \fill [transparent] (-3,0.5) rectangle (8.5,-3);% at frame 1 (when i=0) just draw a transparent background
        \ifnum\i>0\node (step) at (6,-2.5) {Step \i};\fi % start from frame 2 there will be label "step \i"
        \begin{scope}
            \ifnum\i>3\node[circle,draw,addCross={$+$}{$+$}{}{}{10}{black}] (N1) at (1,-0.5) {};\fi
        \end{scope}
        
        \begin{scope}[myBlockOpacity]
            \ifnum\i>8\node[fill=red] (A) at (3,-2) {$A$};\fi
            \ifnum\i>1\node[fill=green!50!black] (B) at (-1,-0.5) {$B$};\fi
            \ifnum\i>10\node[fill=yellow!75!black] (C) at (6,-0.5) {$C$};\fi
            \ifnum\i>5\node (I) at (3,-0.5) {$\displaystyle \int$};\fi
        \end{scope}
        
        \begin{scope}[mySimpleArrow={blue}{cyan}]
            \ifnum\i>0\path[->] (-2.5,-0.5) node[above]{$u$} -- ($(-1.5,-0.5)-(0.5pt,0)$);\fi
            \ifnum\i>2\path[->] ($(-0.5,-0.5)+(0.5pt,0)$) -- ($(0.5,-0.5)-(0.5pt,0)$);\fi
            \ifnum\i>4\path[->] ($(1.5,-0.5)+(0.5pt,0)$) -- ($(2.5,-0.5)-(0.5pt,0)$) node[midway, above] {$\dot{x}$};\fi
            
            \ifnum\i>6\path[->] ($(3.5,-0.5)+(0.5pt,0)$) -- ($(4.5,-0.5)-(0.5pt,0)$) coordinate(x) node[above]{$x$} -- ($(5.5,-0.5)-(0.5pt,0)$);\fi
            \ifnum\i>7\path (4.5,-0.5) |- ($(3.5,-2)+(0.5pt,0)$);\fi
            \ifnum\i>9\path[->] ($(2.5,-2)-(0.5pt,0)$) -| ($(1,-1)-(0,0.5pt)$);\fi
            
            \ifnum\i>11\path[->] ($(6.5,-0.5)+(0.5pt,0)$) -- ++(1.5,0) node[above]{$y$};\fi
        \end{scope}
    \end{tikzpicture}
}
\end{animateinline}
\end{document}

动画效果:

在此处输入图片描述

答案3

还有一个建议:

  • 复制动画,就像在 MWE 中所做的那样
  • 简化元素tikzpicture样式
  • 更短更简单的代码
\documentclass[border=2mm]{standalone}
\usepackage{amsmath,tikz,animate}
\usetikzlibrary{fit,
                positioning,
                quotes}

\newcommand\ppbb{path picture bounding box}
\tikzset{
    arr/.style = {color=#1, very thick, -latex},
    box/.style = {draw, very thick, fill=#1!30,
                  minimum size=16mm, font=\Huge},
    FIT/.style = {draw=red, thick, densely dashed,
                  fit=#1, inner sep=3mm, node contents={}},
    sum/.style = {circle, draw, very thick, minimum size=10mm,
                  path picture={
                    \draw[thick] (\ppbb.north west) -- (\ppbb.south east)
                                 (\ppbb.south west) -- (\ppbb.north east);
                                },
                  node contents={} },
every node/.append style = {inner sep=2pt},
        }
\begin{document}
\begin{animateinline}[loop, controls]{2}
  \multiframe{9}{ii=0+1}{
\begin{tikzpicture}[
node distance = 3mm and 12mm
                    ]
%
\pgfmathsetmacro{\jj}{int(\ii-1)}
\path (-7,3.3) rectangle ++(14,-6.6);
%
    \ifnum\ii > 1
\path (-7,3.3) rectangle ++(14,-6.6)
               node[above left=6mm and 12mm,
                    font=\huge, text=blue] {Step \jj};
%
\node (int) [box=white] {$\int$};
\draw [arr=teal] (int.east) to["$x$"] ++ (1.2,0) coordinate (X);
\path (int) --  coordinate (x) (X);
%    
\node (S1) [sum, left=of int];
\draw [arr=orange] (S1) to["$\dot{x}$"] (int);
    \fi
    \ifnum\ii > 2
\node (A)   [box=orange, below=of int] {$A$};
\draw [arr=teal] (x) |- (A);
    \fi
    \ifnum\ii > 3
\draw [arr=cyan] (A) -| (S1.south) node[above] {$+$};
    \fi
    \ifnum\ii > 4
\node (B)   [box=red, left=of S1] {$B$};
\path (B.west) --  coordinate (d) ++ (-1,0)  coordinate (in);
\draw [arr=teal] (in) to[pos=0.2,"$u$"] (B);
\draw [arr=red] (B)  -- (S1.west)  node[right] {$+$};
    \fi
    \ifnum\ii > 5
\node (C)   [box=olive, right=of int]   {$C$};
\node (S2)  [sum, right=of C];
\draw [arr=olive]  (C)  to["$y$"] (S2);
\draw [arr=violet] (S2.east)  to["$y$"] ++ (1,0);
    \fi
    \ifnum\ii > 6
\node (D)   [box=cyan, above=of int] {$D$};
\draw [arr=teal] (d) |- (D);
\draw [arr=teal] (D) -| (S2.north) node[below] {$+$};
    \fi
    \ifnum\ii > 7
\node [FIT=(B) (D) (S2) (A),
       label={[anchor=south west, inner sep=6mm]%
               south west:$\begin{aligned}
                          \dot{x} & = Ax + Bu\\
                               y  & = Cx + Du
                          \end{aligned}$}];
    \fi
    \end{tikzpicture}
  }
\end{animateinline}
\end{document}    

编辑:最后一步。

在此处输入图片描述

附录(题外话): 我将改变问题中 MWE 1 中显示的控制方案元素的“揭示”顺序。这需要稍长一点的图像代码。

\documentclass[border=3.131592]{standalone}
\usepackage{amsmath,tikz,animate}
\usetikzlibrary{arrows.meta,
                fit,
                positioning,
                quotes}

\newcommand\ppbb{path picture bounding box}
\tikzset{
    arr/.style = {draw=#1, very thick, -Straight Barb},
    box/.style = {draw=#1, very thick, fill=#1!30,
                  minimum size=13mm, font=\Huge},
    FIT/.style = {draw=red, thick, densely dashed, semitransparent,
                  fit=#1, inner sep=3mm, node contents={}},
    sum/.style = {circle, draw, very thick, fill=#1, minimum size=10mm,
                  path picture={
                    \draw[thick] (\ppbb.north west) -- (\ppbb.south east)
                                 (\ppbb.south west) -- (\ppbb.north east);
                                },
                  node contents={} },
every node/.append style = {inner sep=2pt},
        }
\begin{document}
\begin{animateinline}[loop, controls]{2}
  \multiframe{8}{ii=0+1}{
\begin{tikzpicture}[
node distance = 5mm and 15mm
                    ]
%
\pgfmathsetmacro{\jj}{int(\ii-1)}
\path (-5.5,3) rectangle ++(15.5,-6);
%
    \ifnum\ii > 1
\path (-5.5,3) rectangle ++(15.5,-6)
               node[above left, text=blue] {Step \jj};
%
\coordinate (Ia);
\node (I)   [box=red, right=of Ia] {$\int$};
\coordinate[right=of I] (Ib);
\path[arr=red] (Ia) to["$\dot{x}$"] (I);
\path[arr=red] (I)  to[name=d, "$x$"]       (Ib);
\path (I) --  coordinate (a) (Ib);
    \fi
    \ifnum\ii > 2
\node (S1)  [sum=orange, left=of I];
\coordinate[left=of S1] (Bb);
\node (A)  [box=orange, below=of I] {$A$};
\path [arr=orange] (Bb) to["$v$"] (S1.west) node[right] {$+$};
\path [arr=orange] (a) |- (A);
\path [arr=orange] (A) -| (S1.south) 
                        node[above] {$+$}
                        node[pos=0.75,right] {$Ax$};
    \fi
    \ifnum\ii > 3
\node (B)   [box=teal, left=of S1] {$B$};
\coordinate[left=of B] (in);
\path [arr=teal] (in) to[pos=0.2,"$u$"] (B);
\path (in) --  coordinate (d) (B);
\path (B)   to["$v=Bu$" '] (S1);
    \fi
    \ifnum\ii > 4
\node (C)   [box=olive, right=of I]   {$C$};
\coordinate[right=of C] (c);
\draw [arr=olive] (C)  to["$Cx$"] (c);
    \fi
    \ifnum\ii > 5
\node (S2)  [sum=cyan, right=of C];
\coordinate[right=of S2] (out);
\path [arr=olive] (S2)  to["$y$"] (out);
\path (I) -- (S2.west) node[right] {$+$};
\node (D)   [box=cyan, above=of I] {$D$};
\path [arr=cyan] (d) |- (D);
\path [arr=cyan] (D) -| (S2.north) 
                        node[below] {$+$}
                        node[pos=0.75,right] {$Du$};
    \fi
    \ifnum\ii > 6
\node [FIT=(B) (I) (C) (A),
       label={[anchor=south west, inner sep=3mm]%
               south west:$\begin{aligned}
                          \dot{x} & = Ax + Bu\\
                               y  & = Cx 
                          \end{aligned}$}];
    \fi
    \end{tikzpicture}
  }
\end{animateinline}
\end{document}

在此处输入图片描述

用同样的方法你可以绘制 MWE 2 中所示的第二个方案:

\documentclass[border=3.131592]{standalone}
\usepackage{amsmath,tikz,animate}
\usetikzlibrary{arrows.meta,
                fit,
                positioning,
                quotes}

\newcommand\ppbb{path picture bounding box}
\tikzset{
    arr/.style = {draw=#1, very thick, -Straight Barb},
    box/.style = {draw=#1, very thick, fill=#1!30,
                  minimum size=13mm, font=\Huge},
    FIT/.style = {draw=red, thick, densely dashed, semitransparent,
                  fit=#1, inner sep=3mm, node contents={}},
    sum/.style = {circle, draw, very thick, fill=#1, minimum size=10mm,
                  path picture={
                    \draw[thick] (\ppbb.north west) -- (\ppbb.south east)
                                 (\ppbb.south west) -- (\ppbb.north east);
                                },
                  node contents={} },
every node/.append style = {inner sep=2pt},
        }
\begin{document}
\begin{animateinline}[loop, controls]{2}
  \multiframe{6}{ii=0+1}{
\begin{tikzpicture}[
node distance = 5mm and 15mm
                    ]
\draw (-5.5,1) rectangle ++(12.75,-3.75);
%
    \ifnum\ii > 1
\coordinate (Ia);
\node (I)   [box=red, right=of Ia] {$\int$};
\coordinate[right=of I] (Ib);
\path[arr=red] (Ia) to["$\dot{x}$"] (I);
\path[arr=red] (I)  to[name=d, "$x$"]       (Ib);
\path (I) --  coordinate (a) (Ib);
    \fi
    \ifnum\ii > 2
\node (S1)  [sum=orange, left=of I];
\coordinate[left=of S1] (Bb);
\node (A)  [box=orange, below=of I] {$A$};
\path [arr=orange] (Bb) to["$v$"] (S1.west) node[right] {$+$};
\path [arr=orange] (a) |- (A);
\path [arr=orange] (A) -| (S1.south)
                        node[above] {$+$}
                        node[pos=0.75,right] {$Ax$};
    \fi
    \ifnum\ii > 3
\node (B)   [box=teal, left=of S1] {$B$};
\coordinate[left=of B] (in);
\path [arr=teal] (in) to[pos=0.2,"$u$"] (B);
\path (in) --  coordinate (d) (B);
\path (B)   to["$v=Bu$" '] (S1);
    \fi
    \ifnum\ii > 4
\node (C)   [box=olive, right=of I]   {$C$};
\coordinate[right=of C] (c);
\draw [arr=olive] (C)  to["$Cx$"] (c);
\node[below=of B]  {$\begin{aligned}
      \dot{x} & = Ax + Bu\\
           y  & = Cx
      \end{aligned}$};
    \fi
    \end{tikzpicture}
  }
\end{animateinline}
\end{document}

最后一步给出:

在此处输入图片描述

相关内容