65.9K
CodeProject 正在变化。 阅读更多。
Home

制作 2D 物理引擎:空间和物体

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.50/5 (9投票s)

2017年11月7日

CPOL

3分钟阅读

viewsIcon

17798

2D 物理引擎中使用的空间、变换和物体的基础知识。

制作 2D 物理引擎:系列

这是制作 2D 物理引擎系列的第二篇文章。如果您还没有阅读本系列的所有文章,我强烈建议您先绕道浏览一下它们。

  1. 制作 2D 物理引擎:数学部分
  2. 制作 2D 物理引擎:空间和物体
  3. 制作 2D 物理引擎:形状、世界和积分
  4. 制作 2D 物理引擎:质量、惯性和力

必备组件

线性代数的基础知识,包括 2D 向量和 2x2 矩阵,如本系列第一篇文章中所述。

引言

本文旨在介绍局部空间和世界空间的概念,并处理从局部空间到世界空间以及反之亦然的变换。它还概述了物理引擎中物体或物理实体的表示。

空间

空间是无限的范围,对象相对于该范围定义其属性,即旋转和位置。

世界空间

世界中的所有对象在空间中都有明确的位置和旋转,这些位置和旋转是相对于世界原点测量的。世界空间是无处不在的;我们世界中的所有实体都将相对于它放置。

局部空间

局部空间是相对于世界中单个实体的。当在实体的局部空间中测量时,其他实体的属性是相对于该实体测量的。

转换

假设给定的点在世界空间中为 \(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 编写的 Body 结构(取自我正在用 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,
}

但是,此 Body 定义并不完整。随着物理引擎的发展,将向其中添加更多属性。

历史

2017 年 11 月 7 日:首次发布

© . All rights reserved.