在构建2D物理引擎的过程中,理解和实现空间转换是至关重要的。本文将介绍世界空间和本地空间的概念,并探讨如何实现从本地空间到世界空间以及反向的转换。此外,还将概述物理引擎中物体的表示方式。
空间是相对于物体属性(如旋转和位置)定义的无限延伸。在物理引擎中,主要关注两种空间:世界空间和本地空间。
在世界空间中,所有物体都有一个相对于世界原点的确定位置和旋转。世界空间是无处不在的,世界中的所有实体都将相对于它进行定位。
本地空间是相对于世界中的单个实体定义的。当在实体的本地空间中测量时,其他实体的属性是相对于该实体测量的。
设给定点在世界空间中为 \(X\),在相对于某个实体的本地空间中为 \(X'\)。如果该实体的位置(本地空间的原点)为 \(P\),实体的旋转矩阵(本地空间的旋转矩阵)为 \(U = \begin{bmatrix}\cos \theta & -\sin \theta \\ \sin \theta & \cos \theta \end{bmatrix}\)(其中 \(\theta\) 是实体的世界旋转),则可以进行以下转换。
\(X = P + UX'\)
本地空间中的点首先被旋转以适应世界空间的旋转,然后被平移到世界空间的位置。
需要注意的是,本地空间原点或旋转的改变不会影响本地空间中的位置。然而,世界空间中的位置可能会改变。
解上述方程以求得 \(X'\) 将给所需的世界空间到本地空间的转换:
\(X' = U^{-1}(X - P)\)
这给带来了一个问题 - 如何找到矩阵 \(U^{-1}\) 的逆?幸运的是,旋转矩阵是正交的,所以 \(U^{-1} = U^T\),其中 \(U^T\) 是矩阵的转置,已经知道如何计算。现在方程可以重写为:
\(X' = U^T(X - P)\)
空间转换将在整个引擎中使用,以简化数学例程。
物体或实体只是世界中的对象。在案例中,物体是一个可以与环境(或根据其配置,不与环境)物理交互的对象。每个物体都有一些定义性的特征或属性,如位置、速度、扭矩、形状和质量。
物理引擎中的物体本身并不做太多事情。通常,它只负责整合和更新其力、速度和位置。物理引擎 - 或其他外部代码 - 负责管理诸如碰撞之类的交互。物体通常通过对其施加力来操作。然而,在极少数情况下(如将在后面讨论的冲量碰撞解决),速度将被物理引擎直接修改。
物理引擎与世界中的物体的典型交互包括:
在Rust中,一个物体结构可能看起来像下面这样(摘自正在构建的物理引擎):
pub struct Body {
pub position: Vec2,
pub rotation: f32,
pub velocity: Vec2,
pub angular_vel: f32,
force: Vec2,
torque: f32,
pub mass: f32,
pub inertia: f32,
pub coeff_friction: f32,
pub coeff_restitution: f32,
pub shape: Shape,
}