双摆模拟器 — 设计文档

← 返回模拟器   |   ← 返回首页

1. 概述

双摆(Double Pendulum)是经典力学中的混沌系统。它在单摆的末端再铰接一个摆,整个系统由两个二阶非线性微分方程描述,对初始条件极其敏感——初始角度的微小差异(如 0.001 弧度)会在数秒内导致完全不同的运动轨迹。这是"蝴蝶效应"最直观的物理演示之一。

本项目使用 拉格朗日力学 推导运动方程,四阶龙格-库塔法(RK4) 进行数值积分,HTML5 Canvas 实现实时可视化渲染。


2. 物理模型

2.1 广义坐标

取 \(\theta_1\) 和 \(\theta_2\) 为广义坐标,分别表示上摆杆和下摆杆与竖直方向(向下)的夹角,逆时针为正。

           ╱ 支点 O (原点)
         ╱
   l₁  ╱   θ₁ = 摆杆1 与竖直夹角
     ╱
    ● m₁  (x₁, y₁)
     \
   l₂ \   θ₂ = 摆杆2 与竖直夹角
       \
        ● m₂  (x₂, y₂)

2.2 运动学

摆锤 1 的笛卡尔坐标(原点在支点,y 轴向上):

\[ \begin{aligned} x_1 &= l_1 \sin\theta_1 \\ y_1 &= -l_1 \cos\theta_1 \end{aligned} \]

摆锤 2 的笛卡尔坐标:

\[ \begin{aligned} x_2 &= l_1 \sin\theta_1 + l_2 \sin\theta_2 \\ y_2 &= -l_1 \cos\theta_1 - l_2 \cos\theta_2 \end{aligned} \]

对时间求导得到速度:

\[ \begin{aligned} \dot{x}_1 &= l_1 \dot{\theta}_1 \cos\theta_1 \\ \dot{y}_1 &= l_1 \dot{\theta}_1 \sin\theta_1 \\[4pt] \dot{x}_2 &= l_1 \dot{\theta}_1 \cos\theta_1 + l_2 \dot{\theta}_2 \cos\theta_2 \\ \dot{y}_2 &= l_1 \dot{\theta}_1 \sin\theta_1 + l_2 \dot{\theta}_2 \sin\theta_2 \end{aligned} \]

速度平方:

\[ \begin{aligned} v_1^2 &= \dot{x}_1^2 + \dot{y}_1^2 = l_1^2 \dot{\theta}_1^2 \\[4pt] v_2^2 &= \dot{x}_2^2 + \dot{y}_2^2 = l_1^2\dot{\theta}_1^2 + l_2^2\dot{\theta}_2^2 + 2l_1l_2\dot{\theta}_1\dot{\theta}_2\cos(\theta_1 - \theta_2) \end{aligned} \]

2.3 动能与势能

动能 \(T\):

\[ T = \frac{1}{2}m_1 v_1^2 + \frac{1}{2}m_2 v_2^2 \]
\[ \boxed{ T = \frac{1}{2}m_1 l_1^2 \dot{\theta}_1^2 + \frac{1}{2}m_2\big[l_1^2\dot{\theta}_1^2 + l_2^2\dot{\theta}_2^2 + 2l_1l_2\dot{\theta}_1\dot{\theta}_2\cos(\theta_1 - \theta_2)\big] } \]

势能 \(V\)(取支点 O 为势能零点):

\[ \boxed{ V = -(m_1 + m_2)g\,l_1\cos\theta_1 - m_2 g\,l_2\cos\theta_2 } \]

2.4 拉格朗日函数与运动方程

拉格朗日量:

\[ L = T - V \]

代入欧拉-拉格朗日方程:

\[ \frac{d}{dt}\frac{\partial L}{\partial \dot{\theta}_i} - \frac{\partial L}{\partial \theta_i} = 0, \qquad i = 1, 2 \]

得到两个耦合的二阶非线性微分方程,整理为显式形式:

θ₁ 的角加速度

\[ \boxed{ \ddot{\theta}_1 = \frac{ -g(2m_1 + m_2)\sin\theta_1 - m_2 g \sin(\theta_1 - 2\theta_2) - 2\sin(\theta_1 - \theta_2)\,m_2\big[\dot{\theta}_2^2 l_2 + \dot{\theta}_1^2 l_1 \cos(\theta_1 - \theta_2)\big] }{ l_1\big[2m_1 + m_2 - m_2\cos(2\theta_1 - 2\theta_2)\big] } } \]

θ₂ 的角加速度

\[ \boxed{ \ddot{\theta}_2 = \frac{ 2\sin(\theta_1 - \theta_2)\big[ \dot{\theta}_1^2 l_1(m_1 + m_2) + g(m_1 + m_2)\cos\theta_1 + \dot{\theta}_2^2 l_2 m_2 \cos(\theta_1 - \theta_2) \big] }{ l_2\big[2m_1 + m_2 - m_2\cos(2\theta_1 - 2\theta_2)\big] } } \]

关键观察

特征说明
分母两式共享同一分母 \(2m_1 + m_2 - m_2\cos(2\Delta\theta)\)
奇异性分母仅在极端参数下趋近于零,正常参数不会发生
退化为单摆当 \(m_2 \to 0\) 时,\(\ddot{\theta}_1 \approx -\dfrac{g}{l_1}\sin\theta_1\)
混沌来源非线性耦合项 \(\sin(\theta_1 - \theta_2)\) 和乘积项使系统对初值极度敏感

3. 数值方法

3.1 状态空间形式

将两个二阶 ODE 转化为四个一阶 ODE:

\[ \mathbf{y} = \begin{bmatrix} y_0 \\ y_1 \\ y_2 \\ y_3 \end{bmatrix} = \begin{bmatrix} \theta_1 \\ \theta_2 \\ \dot{\theta}_1 \\ \dot{\theta}_2 \end{bmatrix}, \qquad \frac{d\mathbf{y}}{dt} = \mathbf{f}(\mathbf{y}) = \begin{bmatrix} \dot{\theta}_1 \\ \dot{\theta}_2 \\ \ddot{\theta}_1(\theta_1, \theta_2, \dot{\theta}_1, \dot{\theta}_2) \\ \ddot{\theta}_2(\theta_1, \theta_2, \dot{\theta}_1, \dot{\theta}_2) \end{bmatrix} \]

3.2 四阶龙格-库塔法 (RK4)

每步计算四个中间斜率:

\[ \begin{aligned} \mathbf{k}_1 &= \mathbf{f}(\mathbf{y}_n) \\[3pt] \mathbf{k}_2 &= \mathbf{f}\big(\mathbf{y}_n + \tfrac{h}{2}\mathbf{k}_1\big) \\[3pt] \mathbf{k}_3 &= \mathbf{f}\big(\mathbf{y}_n + \tfrac{h}{2}\mathbf{k}_2\big) \\[3pt] \mathbf{k}_4 &= \mathbf{f}(\mathbf{y}_n + h\mathbf{k}_3) \end{aligned} \]

加权更新:

\[ \mathbf{y}_{n+1} = \mathbf{y}_n + \frac{h}{6}\big(\mathbf{k}_1 + 2\mathbf{k}_2 + 2\mathbf{k}_3 + \mathbf{k}_4\big) \]

3.3 方法选择

方法局部截断误差优点缺点
欧拉法\(O(h^2)\)简单能量漂移严重,需极小步长
Verlet / 辛积分\(O(h^2)\)长期能量守恒好速度依赖力时需处理
RK4\(O(h^5)\)精度高,实现适中每步 4 次函数求值

RK4 的 \(O(h^5)\) 局部截断误差使其在 \(h = \tfrac{1}{240}\) 步长下已非常精确。

3.4 步长策略


4. 系统架构

┌──────────────────────────────────────────────────┐
│                HTML / Canvas 页面                  │
│                                                    │
│  ┌──────────┐  ┌──────────────┐  ┌─────────────┐ │
│  │  信息面板  │  │   参数面板     │  │  按钮控制   │ │
│  │  θ₁, θ₂  │  │ l₁,l₂,m₁,m₂ │  │ 暂停/轨迹   │ │
│  │  ω₁, ω₂  │  │     g, 速度   │  │ 混沌/重置   │ │
│  │   FPS    │  │  (实时可调)  │  │             │ │
│  └──────────┘  └──────────────┘  └─────────────┘ │
│                                                    │
│  ┌──────────────────────────────────────────────┐ │
│  │              渲染引擎 (Canvas 2D)              │ │
│  │  ┌─────────┐  ┌──────────┐  ┌─────────────┐ │ │
│  │  │ 摆杆+锤  │  │ 发光辉光  │  │ HSLA 轨迹    │ │ │
│  │  │ (线条+圆)│  │ (径向渐变)│  │ (渐变拖尾)   │ │ │
│  │  └─────────┘  └──────────┘  └─────────────┘ │ │
│  └──────────────────┬───────────────────────────┘ │
│                     │                              │
│  ┌──────────────────▼───────────────────────────┐ │
│  │              物理引擎                          │ │
│  │  ┌──────────────────────┐  ┌───────────────┐ │ │
│  │  │  Pendulum 类          │  │  params 全局   │ │ │
│  │  │  - theta1, theta2    │  │  参数对象      │ │ │
│  │  │  - omega1, omega2    │  │  (l1,l2,m1,   │ │ │
│  │  │  - derivatives()      │  │   m2,g,speed) │ │ │
│  │  │  - step(dt) / RK4    │  └───────────────┘ │ │
│  │  │  - getPositions()     │                    │ │
│  │  │  - trail[] 轨迹缓存   │                    │ │
│  │  └──────────────────────┘                    │ │
│  └──────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────┘

5. 使用指南

5.1 基本操作

功能操作说明
拖拽摆锤鼠标按住摆锤 2 拖动锁定角度,角速度归零,从任意初始状态释放
暂停/继续按钮或空格键暂停物理模拟,仔细分析当前状态
轨迹开关按钮切换显示或隐藏摆锤 2 的运动轨迹
混沌模式按钮切换显示 6 个初始角偏移 0.001 rad 的副本,直观展示蝴蝶效应
重置按钮恢复初始角度,清空轨迹,从初始状态重新开始

5.2 参数调节

右侧面板提供多个实时滑块,所有参数 即时生效,无需暂停或重置:

5.3 实验探索


6. 混沌演示原理

混沌模式下,系统生成 6 个与主摆参数完全相同的摆,但初始角度各偏移 ±0.001 弧度:

初始角差异最大仅 0.006 rad(约 0.34°)
          ↓
  由于运动方程的非线性耦合
          ↓
  数秒内 6 个摆的轨迹完全分道扬镳
          ↓
  直观展示混沌系统对初值的极端敏感性

这是洛伦兹(Edward Lorenz)"蝴蝶效应"最优雅的物理可视化——确定性方程产生不可预测的行为。


7. 文件结构

simulation/
├── pom.xml
└── src/
    └── main/
        └── resources/
            ├── double-pendulum.html          ← 双摆模拟器
            └── 双摆模拟器设计文档.html         ← 本文档

纯静态 HTML 文件,无需编译、无需后端、无需 npm install。用浏览器直接打开即可运行。


8. 扩展方向