我怎样才能使这个双摆动起来?

我怎样才能使这个双摆动起来?

我想可视化双摆的动画,但我不知道如何做,因为我对这个animate包还不熟悉,这里是双摆(tikz)的代码:

    \documentclass[tikz,border=8mm]{standalone}
\usetikzlibrary{backgrounds,angles,quotes}
\begin{document}

\begin{tikzpicture}[%
angle eccentricity=1.2,
ball/.style={circle, inner sep=0pt, minimum size=2mm, fill=blue, draw=blue, label=right:$m$},
background rectangle/.style={fill=black},
show background rectangle]

\draw[thick, white] (-2,0) --(2,0);
\draw[white] (0,0) coordinate (b0) foreach \i [count=\ni] in {-70,-55} {--++(\i:2cm) node[midway,auto]{$l$} node[ball] (b\ni) {}};

\foreach \i [count=\auxi] in {b0,b1}{
    \draw[dashed, white] (\i)--++(-90:1.8cm) coordinate[pos=.75] (aux\auxi);
} 

\draw pic["$\theta_1$", draw, white, angle radius=1.2cm] {angle=aux1--b0--b1};
\draw pic["$\theta_2$", draw, white, angle radius=1.2cm] {angle=aux2--b1--b2};

\end{tikzpicture}

\end{document}

蒂克

答案1

(使用 TikZ 绘制动画帧)

要使双摆动起来,我们必须求解运动方程,它是一组常微分方程 (ODE)。对于两个不同点质量的无摩擦双摆,摆角的微分方程θ1θ2在法语维基百科文章第 1 节末尾给出:

https://fr.wikipedia.org/wiki/Pendule_double#Mise_en_%C3%A9quation_utilisant_l'approche_lagrangienne

方程 (1) 和 (2) 都是隐式的,与角加速度耦合。为了使第一个方程显式化,将方程 (2) 代入 (1),然后 (1) 解析为\ddot{θ1} .

为了在 LaTeX 中求解 ODE 系统,我们可以使用包pst-ode(方法:RKF45)。这是一个 PSTricks 包,但多亏了卢普斯特里克,由 Marcel Krüger 开发的 PostScript 解释器,下面的示例可以直接用lualatex;ps2pdf排版,不再需要(Ghostscript)。

timeTheta1Theta2.dat逐行读取第一次运行期间写入的文件以获取每一步的时间和角度。最后用绘制动画帧TikZ

这些是您可能想要使用的参数:

/tEnd 70 def                                % time span to be simulated [s]
/m1 1 def                                   % mass1 [kg]
/m2 1 def                                   % mass2 [kg]
/l1 2 def                                   % pendulum1 length [m]
/l2 2 def                                   % pendulum2 length [m]
/G 9.81 def                                 % acceleration [m/s^2]
/theta1zero 179 Pi mul 180 div def          % theta1_0=179°
/theta2zero 180 Pi mul 180 div def          % theta2_0=180°

70 秒以上的实时动画。单击即可运行动画(如果 Firefox 太慢,请尝试使用基于 Chromium 的浏览器。)

排版三次lualatex

%\PassOptionsToPackage{dvisvgm}{animate} % dvilualatex <file> ; dvisvgm --zoom=-1 --font-format=woff2 --bbox=papersize <file>.dvi 
\documentclass[margin=1mm,varwidth]{standalone} 
 
\usepackage{pst-ode} 
\usepackage[controls,autoplay]{animate} 
\usepackage{tikz} 
\usepackage{listofitems} % read space separated items 
\usepackage{siunitx} 
\usepackage{xfp} 
\usepackage[T1]{fontenc} 
 
% adjustable parameters & definitions 
\pstVerb{ 
  tx@Dict begin 
  /tEnd 70 def                                % time span to be simulated [s] 
  /m1 1 def                                   % mass1 [kg] 
  /m2 1 def                                   % mass2 [kg] 
  /l1 2 def                                   % pendulum1 length [m] 
  /l2 2 def                                   % pendulum2 length [m] 
  /G 9.81 def                                 % acceleration [m/s^2] 
  /theta1zero 179 Pi mul 180 div def          % theta1_0=179° 
  /theta2zero 180 Pi mul 180 div def          % theta2_0=180° 
  /N (cvi(tEnd*25+1)) AlgParser cvx exec def  % (integer) number of time steps (for 25 frames per s) + 1 
  % 
  /M2 (m2/(m1+m2)) AlgParser cvx exec def     % some constants 
  /rM2 (1/M2) AlgParser cvx exec def 
  /l12 (l1/l2) AlgParser cvx exec def 
  /l21 (l2/l1) AlgParser cvx exec def 
  /G1 (G/l1) AlgParser cvx exec def 
  /G2 (G/l2) AlgParser cvx exec def 
  /G1M2 (G1/M2) AlgParser cvx exec def 
  % 
  /theta1Dot (x[2]) AlgParser cvx def         % 1st order ODE system 
  /theta2Dot (x[3]) AlgParser cvx def 
  /omega1Dot (((G1*sin(x[1])-x[2]^2*sin(x[0]-x[1]))*cos(x[0]-x[1])-l21*x[3]^2*sin(x[0]-x[1])-G1M2*sin(x[0])) 
    /(rM2-cos(x[0]-x[1])^2)) AlgParser cvx def 
  /omega2Dot (-l12*(omega1Dot*cos(x[0]-x[1])-x[2]^2*sin(x[0]-x[1]))-G2*sin(x[1])) AlgParser cvx def 
  end 
} 
 
% solve equations of motion 
\pstODEsolve[algebraicAll,saveData]{timeTheta1Theta2}{% PS variable that takes result list 
  t | x[0]*180/Pi-90 | x[1]*180/Pi-90 % table format of data to be saved in timeTheta1Theta2 
}{0}{tEnd}{N}{                        % t_0, t_end, number of  time steps + 1 
  theta1zero | theta2zero | 0 | 0     % initial conditions 
}{ 
  theta1Dot | theta2Dot | omega1Dot | omega2Dot  % ODE system's RHS 
} 
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% \fileopenr{<file stream>}{<file name>}, opens file for reading 
\newcommand\fileopenr[2]{% 
  \newread#1% 
  \immediate\openin#1=#2% 
} 
% \readtolist[<sep char>]{<file stream>}{\list} 
% reads a line from file stream and splits at <sep char> into \list[1], \list[2], ... 
\newcommand\readtolist[3][,]{{% 
  \setsepchar{#1}% 
  \immediate\read#2 to \inputline% 
    \ifeof#2 
      \immediate\closein#2% 
      \ifdefined\multiframebreak\multiframebreak\fi% 
    \else% 
      \greadlist*#3\inputline% 
    \fi% 
}} 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
 
\begin{document} 
 
$l_1=l_2=\qty{2}{\metre}$; $m_1=m_2=\qty{1}{\kilogram}$\\ 
\IfFileExists{timeTheta1Theta2.dat}{}{\end{document}}% 
\begin{animateinline}{25} 
  \fileopenr{\data}{timeTheta1Theta2.dat}% 
  \readtolist[ ]{\data}{\table}% 
  \multiframe{100000}{}{ 
    \begin{tikzpicture}% 
      \useasboundingbox (-4.2,-4.2) rectangle (4.2,4.2); 
      \filldraw (0,0) -- ++(\table[2]:2) circle[radius=1mm] -- ++(\table[3]:2) circle[radius=1mm]; 
      \filldraw [fill=white] (0,0) circle [radius=1pt]; 
      \node[anchor=north west, inner sep=0pt] at (-4.2,4.2) {\strut$t=\qty{\fpeval{trunc(\table[1])}}{\second}$}; 
    \end{tikzpicture}% 
    \readtolist[ ]{\data}{\table}% 
  } 
\end{animateinline} 
 
\end{document} 

相关内容