Pikuma_2DPhysicsEngine_总结

25 年 10 月 7 日 星期二
1780 字
9 分钟

大概总共花了一周左右学习了一下这个课程,教的蛮好的。非常的深入浅出,比较注重一些细节实现的真正理解,繁杂公式的也会带着逐步推导。该博客用于自我回顾一下课程项目简单复习总结记录一下。

整体课程内容

粒子物理 (Particle Physics)

粒子物理是入门阶段。在这个阶段,重点是简化对象和运动,以便分析物理特性与实现一些基本功能,如线性运动。

质点 (Point Mass)

  • 粒子对象(Particles)是简单的物体,没有形状,因此不涉及旋转与碰撞
  • 每个粒子本质上被视为一个点,包含位置、速度、加速度(均为向量 Vec2)和质量(float)。
  • 讨论到了质量的倒数inverse of the mass)的概念,该值在物理计算中比质量本身使用得更频繁。

积分 (Integration)

  • 积分用于更新粒子的位置和速度。
  • 主要讲解了欧拉积分法(Euler method),特别是半隐式欧拉方法(Semi-implicit Euler),通过当前加速度计算下一时刻的速度 (Vn+1V_{n+1}),再用 Vn+1V_{n+1} 更新下一时刻的位置 (Xn+1X_{n+1})。
  • 稍微提到了Verlet 积分(Verlet integration),建议如果后续处理软体(Soft Bodies)和约束时,可以考虑使用 Verlet 积分。
  • 积分步骤(integrate 方法)通过每帧接收 时间增量Δt\Delta tdt)作为参数。

力、运动 (Force, Motion)

  • 力在每帧模拟步骤开始时被施加和累积(addForce),并在积分(integrate)后被清除(clearForces)。
  • 课程实现了一些力(通过静态辅助函数 force::generate...):
    • 重力(Weight Force):模拟重力向下拉动粒子。
    • 推力/风力(Push/Wind Force):可以模拟空气阻力或通过键盘控制的推力。
    • 阻力(Drag Force):简化的阻力公式,其中多个常数被一个单独的常数 kk 代替,简化为 kk 乘以速度。
    • 摩擦力(Friction Force):通过一个常数 kk(表示表面粗糙度或光滑度)进行简化处理。
    • 万有引力(Gravitational Force):模拟两个粒子之间的相互吸引力,公式中使用了最小和最大距离的参数来限制距离平方的值,以确保视觉效果的稳定和有趣。
    • 弹簧力(Spring Force):基于胡克定律,力与位移(Δl\Delta l,即拉伸或压缩量)成正比,并使用弹簧常数 KK(刚度)和剩余长度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,通常用希腊字母 τ\tau 表示)定义为力使物体绕某个轴旋转的能力。
  • 扭矩的计算与力的大小 FF、距离 dd(力臂)和力与距离向量之间的角度 β\beta 的正弦值有关。
  • 转动惯量(Moment of Inertia,或称角动量 angular mass)决定了实现所需角加速度所需的扭矩大小。每种形状都有对应的转动惯量公式。
  • 刚体具有恢复系数coefficient of restitution, ϵ\epsilonee)和摩擦系数coefficient of friction)属性。
  • 冲量(Impulse)是一种瞬间改变物体速度(线性和角速度)的力。实现上便是直接修改速度值。

碰撞检测 (Collision Detection)

  • 碰撞检测主要关注分离轴定理(Separating Axis Theorem, SAT)。
  • SAT 算法仅对凸多边形有效。
  • SAT 通过检查物体在各个轴上的投影是否重叠来确定碰撞。
  • 碰撞检测会返回最小分离距离minimum separation),负值表示重叠(穿透)。
  • 碰撞信息存储在 Contact 结构体中,包括刚体 A 和 B 的指针、碰撞法线、穿透深度以及碰撞的起始和结束点。

基于瞬时冲量的碰撞/重叠解算 (Impulse-based Collision/Overlap Resolution)

  • 该阶段的碰撞解算暂时使用瞬时冲量来即时修正速度,从而解决重叠和弹跳。
  • 冲量公式是基于动量守恒和恢复系数 ϵ\epsilon 导出的,并结合了线性和角速度分量。
  • 冲量计算中使用了质量倒数inverse mass),质量为 0(静态物体)的物体,其质量倒数为 0。
  • 摩擦(Friction)通过在雅可比矩阵中添加切向(Tangent)的第二行来实现。切向冲量必须被限制在法向冲量乘以摩擦系数 μ\mu 的范围内。
  • 多重接触点(Multiple Contact Points)的解算需要使用 裁剪(Clipping)技术,基于 SAT 找到的参考面reference face)和入射面incident face)进行线段裁剪。

约束 (Constraints)

约束是用于限制物体运动或保持物体之间关系的机制。约束的概念为解算运动/

  • 约束类型: 基础 Constraint 类作为父类。具体的约束包括关节约束JointConstraint,限制两物体间距离,如链条或铰链)和穿透约束PenetrationConstraint,用于碰撞解算)。
  • 核心数学: 约束解算大量使用拉格朗日力学的原理,并涉及求解一个线性系统 Ax=bA\mathbf{x}=\mathbf{b} 来找到拉格朗日乘数 λ\lambda(即冲量的大小)。
  • 雅可比矩阵(Jacobian): 约束的核心组件。雅可比矩阵 JJ 将速度从世界空间映射到约束空间,并将冲量从约束空间映射回世界空间(JTJ^T)。对于两个刚体的约束,雅可比矩阵通常是 1x6 或 2x6 的维度(包含 A/B 的线性和角速度分量)。
  • 求解方法: 课程使用高斯-赛德尔(Gauss-Seidel)迭代法来求解 λ\lambda
  • 应用冲量: 求解得到的 λ\lambda 乘以雅可比矩阵的转置 JTJ^T 即可得到作用于刚体的最终冲量向量。然后将该冲量分别应用于刚体的线性和角速度。

更新中...

文章标题:Pikuma_2DPhysicsEngine_总结

文章作者:DWHITE

文章链接:https://dr9k69ai79.github.io/MyBlog/posts/pikuma_2dphysicsengine_总结[复制]

最后修改时间:


商业转载请联系站长获得授权,非商业转载请注明本文出处及文章链接,您可以自由地在任何媒体以任何形式复制和分发作品,也可以修改和创作,但是分发衍生作品时必须采用相同的许可协议。
本文采用CC BY-NC-SA 4.0进行许可。