如何用 TikZ 创建动画人物

如何用 TikZ 创建动画人物

我正在尝试制作动画图片。在下面的两张图片中,我希望球在第一张图片中在半圆内移动,在钟摆上沿圆弧移动,并在 x 轴上沿着中心质量投影移动。投影应该使钟摆呈正弦运动。

编辑:虚线弧问题已由@Black Mild 修复。

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

这是我的代码:

\documentclass[preview,border=1cm]{standalone}
\usepackage{pgfplots}
\usepackage{tikz}
\usepackage{xcolor}
\usetikzlibrary{arrows,shapes,positioning}
\usetikzlibrary{decorations.markings,decorations.pathmorphing,
decorations.pathreplacing}
\usetikzlibrary{calc,patterns,shapes.geometric}
%Circle
\begin{document}
\begin{tikzpicture}
\draw[line width=1pt,color=red,-latex](-3,0)--(3,0);
\draw[fill=orange!20] (2,2) -- (-2,2) arc(180:360:2) --cycle;
\draw[fill=gray] (-1.8,1.8) circle
(5pt)node[font=\tiny]{$\color{white}{m}$};
\draw[red,dashed](-2,1.8)--(-2,0)node[above,font=\large]{$-x_m$};
\draw[red,dashed](2,1.8)--(2,0)node[above,font=\large]{$x_m$};
\fill [pattern=north east lines] (-3,-0.2) rectangle (3,0); 
\end{tikzpicture}
%pendulum
\begin{tikzpicture}
\draw[line width=1pt,color=gray,dashed](0,-2)--(0,4);
\draw[line width=1pt,color=gray](0,4)--(3,0);
\draw[line width=1pt,color=red,-latex](-4,-1)--(4,-1);
\draw[red,dashed](3,0)--(3,-1)node[below,font=\large]{$x_m$};
\draw[red,dashed](-3,0)--(-3,-1)node[above,font=\large]{$-x_m$};
\draw[fill=gray] (3,0) circle
(5pt)node[font=\tiny]{$\color{white}{m}$};
\draw[dashed] (0,4) circle(5cm);

\end{tikzpicture}
\end{document}

答案1

由于您想为钟摆的摆动制作动画,我建议使用极坐标的另一种方法。这会让事情变得容易得多(我使用了 Black Mild 的精彩答案作为基础,因此设计相似):

\documentclass[border=10pt]{standalone}
\usepackage{animate}
\usepackage{tikz}

\pgfmathsetmacro{\pendulumswing}{40}
\pgfmathsetmacro{\pendulumlength}{5}

\begin{document}
    \begin{animateinline}[controls, palindrome]{45}
        \multiframe{45}{rt=0+4}{%
            \begin{tikzpicture}[line width=1pt]
                \draw[dashed] (0:0) -- (90:{-\pendulumlength}) coordinate (o);
                \draw[dashed] ({90-\pendulumswing}:{-\pendulumlength}) coordinate (a)
                    arc[start angle={90-\pendulumswing}, end angle={90+\pendulumswing}, radius={-\pendulumlength}] coordinate (b);
                \draw[dashed, red] (a) -- (a |- o) coordinate (c) node[below] {$-x_m$};
                \draw[dashed, red] (b) -- (b |- o) coordinate (d) node[below] {$x_m$};
                \draw[-stealth, red] ([xshift=-1cm]c) -- ([xshift=1cm]d);
                
                % variable \rt goes from 0 to 180
                % cos(\rt) returns a value between -1 and 1 following a (co)sine curve
                \pgfmathsetmacro{\pendulumangle}{cos(\rt)*\pendulumswing}
                \draw (0:0) -- ({90+\pendulumangle}:{-\pendulumlength})
                      node[circle, fill=blue, text=white] {$\mathbf{m}$};
            \end{tikzpicture}%
        }%
    \end{animateinline}
\end{document}

在此处输入图片描述

\pendulumswing会获取摆锤向左或向右旋转的最大角度。宏\pendulumlength会获取摆锤的长度。更改这些值可获得更长的摆锤或具有不同偏转的摆锤。

编译并使用 Acrobat 播放动画。使用其他查看器,动画可能无法正常工作。以下是输出的 GIF 近似值:

在此处输入图片描述


用类似的方法,你可以画出第一个带球的图形:

\documentclass[border=10pt]{standalone}
\usepackage{animate}
\usepackage{tikz}
\usetikzlibrary{patterns}

\pgfmathsetmacro{\pendulumswing}{80}
\pgfmathsetmacro{\pendulumlength}{3}
\pgfmathsetmacro{\floordepth}{0.2}
\pgfmathsetmacro{\bobsize}{.75}

\begin{document}
    \begin{animateinline}[controls, palindrome]{45}
        \multiframe{45}{rt=0+4}{%
            \begin{tikzpicture}[line width=1pt]
                \coordinate (o) at (90:{-\pendulumlength-\bobsize/2});
                \fill[orange!10, draw=black] (180:{-\pendulumlength-\bobsize/2}) coordinate (a)
                    arc[start angle={180}, end angle={0}, radius={-\pendulumlength-\bobsize/2}] coordinate (b) -- cycle;
                \coordinate (a) at ({90-\pendulumswing}:{-\pendulumlength-\bobsize/2});
                \coordinate (b) at ({90+\pendulumswing}:{-\pendulumlength-\bobsize/2});
                \draw[dashed, red] (a) -- (a |- o) coordinate (c) node[below={\floordepth*1cm}] {$-x_m$};
                \draw[dashed, red] (b) -- (b |- o) coordinate (d) node[below={\floordepth*1cm}] {$x_m$};
                \fill[pattern=north east lines] ([xshift=-1cm]c) rectangle ([xshift=1cm, yshift={\floordepth*-1cm}]d); 
                \draw[-stealth, red] ([xshift=-1cm]c) -- ([xshift=1cm]d);
                
                % variable \rt goes from 0 to 180
                % cos(\rt) returns a value between -1 and 1 following a (co)sine curve
                \pgfmathsetmacro{\pendulumangle}{cos(\rt)*\pendulumswing}
                \node[circle, draw, fill=gray, text=white, text width={\bobsize*1cm}, inner sep=0pt, align=center] 
                    at ({90+\pendulumangle}:{-\pendulumlength}) {$\mathbf{m}$};
            \end{tikzpicture}%
        }%
    \end{animateinline}
\end{document}

在此处输入图片描述


如果动画变得太慢(因为它有太多帧或由于其他原因),您可以调整帧速率和/或减少步数,例如使用:

% [...]
    \begin{animateinline}[controls, palindrome]{30}
        \multiframe{30}{rt=0+6}{%
            % [...]
        }
    \end{animateinline}
% [...]
    

你只需要确保宏\rt从 0 到 180。这里的\multiframe{30}{rt=0+6}意思是,变量\rt将从 0 开始,每帧增加 6,总共 30 帧(导致\rt最后一帧等于 180)。

答案2

给你!a\clip用于获取所需的弧。PS:我厌倦了清理你的代码 ^^

在此处输入图片描述

\documentclass[tikz,border=1cm]{standalone}
\usepackage{amsmath,amssymb}
\begin{document}
% pendulum
\begin{tikzpicture}[line width=1pt]
\def\a{3}
\def\b{4}
\pgfmathsetmacro{\c}{sqrt(\a*\a+\b*\b)}     
\draw[dashed] (0,-1)--(0,\b);
\draw (0,\b)--(\a,0);
\draw[red,-latex] (-\a-1,-1)--(\a+1,-1);
\draw[red,dashed] 
(\a,0)--(\a,-1) node[below]{$x_m$}
(-\a,0)--(-\a,-1) node[below]{$-x_m$};
\begin{scope}
\clip (0,\b)--(\a,0)--(\a,-1)--(-\a,-1)--(-\a,0)--cycle;    
\draw[dashed] (0,\b) circle(\c);    
\end{scope}
\path (\a,0) node[circle,fill=blue,text=white]{$\mathbf{m}$};
\end{tikzpicture}
\end{document}

相关内容