大概总共花了一周左右学习了一下这个课程,教的蛮好的。非常的深入浅出,比较注重一些细节实现的真正理解,繁杂公式的也会带着逐步推导。该博客用于自我回顾一下课程项目简单复习总结记录一下。
整体课程内容
粒子物理 (Particle Physics)
粒子物理是入门阶段。在这个阶段,重点是简化对象和运动,以便分析物理特性与实现一些基本功能,如线性运动。
质点 (Point Mass)
- 粒子对象(Particles)是简单的物体,没有形状,因此不涉及旋转与碰撞。
- 每个粒子本质上被视为一个点,包含位置、速度、加速度(均为向量
Vec2)和质量(float)。 - 讨论到了质量的倒数(
inverse of the mass)的概念,该值在物理计算中比质量本身使用得更频繁。
积分 (Integration)
- 积分用于更新粒子的位置和速度。
- 主要讲解了欧拉积分法(Euler method),特别是半隐式欧拉方法(Semi-implicit Euler),通过当前加速度计算下一时刻的速度 (),再用 更新下一时刻的位置 ()。
- 稍微提到了Verlet 积分(Verlet integration),建议如果后续处理软体(Soft Bodies)和约束时,可以考虑使用 Verlet 积分。
- 积分步骤(
integrate方法)通过每帧接收 时间增量( 或dt)作为参数。
力、运动 (Force, Motion)
- 力在每帧模拟步骤开始时被施加和累积(
addForce),并在积分(integrate)后被清除(clearForces)。 - 课程实现了一些力(通过静态辅助函数
force::generate...):- 重力(Weight Force):模拟重力向下拉动粒子。
- 推力/风力(Push/Wind Force):可以模拟空气阻力或通过键盘控制的推力。
- 阻力(Drag Force):简化的阻力公式,其中多个常数被一个单独的常数 代替,简化为 乘以速度。
- 摩擦力(Friction Force):通过一个常数 (表示表面粗糙度或光滑度)进行简化处理。
- 万有引力(Gravitational Force):模拟两个粒子之间的相互吸引力,公式中使用了最小和最大距离的参数来限制距离平方的值,以确保视觉效果的稳定和有趣。
- 弹簧力(Spring Force):基于胡克定律,力与位移(,即拉伸或压缩量)成正比,并使用弹簧常数 (刚度)和剩余长度(
rest length,平衡距离)。
不考虑碰撞与旋转 (No Collision, No Rotation)
- 在粒子物理阶段,对象被简化为质点,不具备旋转能力。
- 简单的边界碰撞是通过翻转速度分量来实现弹跳效果。
- 粒子可以被用来模拟软体(Soft Bodies),通过多个粒子通过弹簧(基于Spring Force)相互连接来维持形状。
刚体物理 (Rigid Body Physics)
刚体物理是课程的深入部分,对象开始具有形状和旋转能力,并且涉及到碰撞检测与约束解算。
基本图形(圆形、凸多边形)
- 刚体(Bodies)内部包含一个
Shape对象。 - 支持的几何形状包括圆形(
CircleShape)、多边形(PolygonShape)以及特殊的矩形(BoxShape)。 - 所有形状的顶点都是在局部空间(
local space,即以物体原点(body.position)/质心为原点的坐标系)中定义的。 - 凸多边形(Convex Polygons)是基于碰撞检测算法(SAT)的限制。
- 刚体需要具备局部空间到世界空间(
local space to world space)和世界空间到局部空间的坐标转换函数,用于处理旋转和平移。
积分
- 刚体的积分被分为线性积分(
integrateLinear)和角积分(integrateAngular)。 - 通过积分更新对象的速度和角速度,然后更新位置和旋转角度。
力、冲量、运动、旋转、摩擦
- 刚体除了累积合力(
sumForces)外,还累积扭矩(sumTorque)。 - 扭矩(Torque,通常用希腊字母 表示)定义为力使物体绕某个轴旋转的能力。
- 扭矩的计算与力的大小 、距离 (力臂)和力与距离向量之间的角度 的正弦值有关。
- 转动惯量(Moment of Inertia,或称角动量
angular mass)决定了实现所需角加速度所需的扭矩大小。每种形状都有对应的转动惯量公式。 - 刚体具有恢复系数(
coefficient of restitution, 或 )和摩擦系数(coefficient of friction)属性。 - 冲量(Impulse)是一种瞬间改变物体速度(线性和角速度)的力。实现上便是直接修改速度值。
碰撞检测 (Collision Detection)
- 碰撞检测主要关注分离轴定理(Separating Axis Theorem, SAT)。
- SAT 算法仅对凸多边形有效。
- SAT 通过检查物体在各个轴上的投影是否重叠来确定碰撞。
- 碰撞检测会返回最小分离距离(
minimum separation),负值表示重叠(穿透)。 - 碰撞信息存储在
Contact结构体中,包括刚体 A 和 B 的指针、碰撞法线、穿透深度以及碰撞的起始和结束点。
基于瞬时冲量的碰撞/重叠解算 (Impulse-based Collision/Overlap Resolution)
- 该阶段的碰撞解算暂时使用瞬时冲量来即时修正速度,从而解决重叠和弹跳。
- 冲量公式是基于动量守恒和恢复系数 导出的,并结合了线性和角速度分量。
- 冲量计算中使用了质量倒数(
inverse mass),质量为 0(静态物体)的物体,其质量倒数为 0。 - 摩擦(Friction)通过在雅可比矩阵中添加切向(Tangent)的第二行来实现。切向冲量必须被限制在法向冲量乘以摩擦系数 的范围内。
- 多重接触点(Multiple Contact Points)的解算需要使用 裁剪(Clipping)技术,基于 SAT 找到的参考面(
reference face)和入射面(incident face)进行线段裁剪。
约束 (Constraints)
约束是用于限制物体运动或保持物体之间关系的机制。约束的概念为解算运动/
- 约束类型: 基础
Constraint类作为父类。具体的约束包括关节约束(JointConstraint,限制两物体间距离,如链条或铰链)和穿透约束(PenetrationConstraint,用于碰撞解算)。 - 核心数学: 约束解算大量使用拉格朗日力学的原理,并涉及求解一个线性系统 来找到拉格朗日乘数 (即冲量的大小)。
- 雅可比矩阵(Jacobian): 约束的核心组件。雅可比矩阵 将速度从世界空间映射到约束空间,并将冲量从约束空间映射回世界空间()。对于两个刚体的约束,雅可比矩阵通常是 1x6 或 2x6 的维度(包含 A/B 的线性和角速度分量)。
- 求解方法: 课程使用高斯-赛德尔(Gauss-Seidel)迭代法来求解 。
- 应用冲量: 求解得到的 乘以雅可比矩阵的转置 即可得到作用于刚体的最终冲量向量。然后将该冲量分别应用于刚体的线性和角速度。