1

我正在开发一个碰撞预测系统(语言在这里真的无关紧要)并且我正在寻找一种方法来预测给定时间后两个对象的碰撞箱的碰撞。我拥有的变量是:

  • 第一个实体
  • 第二实体
  • 第一个和第二个实体实体边界框的最大和最小 XYZ(“最高”角和“最低”角)
  • 第一个和第二个实体速度(我们假设它是常数)
  • 时间

到目前为止,我尝试的是plausable entity position after given time基于计算hitboxes max and min positions两个实体的 then 并检查这些位置是否发生碰撞。我这样做的方式由很多循环组成,而且效率极低,尽管我没有使用任何数学公式,因为我还没有找到。

StackOverflow 上有一个,但用于 2D 碰撞预测,你可以在这里找到它。

我希望有人帮助我将其扩展到 3D 空间。

4

1 回答 1

3

这就是我将如何做到的。首先,找出两个框的 X 坐标重叠的时间间隔。您可以通过求解 t 中的两个线性方程来做到这一点,表示 X 坐标刚刚接触的时间:

  • 实体 1 在时间 t 的最小 X = 实体 2 在时间 t 的最大 X
  • 实体 1 在时间 t 的最大 X = 实体 2 在时间 t 的最小 X

如果您需要帮助设置该部分,请告诉我!

现在,为 Y 坐标解决同样的问题。如果 Y 的区间不与 X 的区间相交,则框不会发生碰撞。如果间隔确实相交,请走十字路口并继续前进。

解决 Z 坐标的问题以获得另一个区间。如果 Z 的区间不与 X 和 Y 的区间相交,则框不会发生碰撞。如果间隔确实相交,请选择相交。

现在你有一个时间间隔 [t1, t2] 表示所有三个盒子坐标重叠的时间点——换句话说,所有盒子重叠的时间点!所以 t1 是它们碰撞的时间点。

(另一种方法是用椭圆体替换命中框并像在另一个 StackOverflow 线程中一样求解二次方程。但是,在这种情况下,数学实际上更难。使用轴对齐的框意味着您可以将问题分解为每个坐标独立并坚持线性方程。)

编辑:根据要求,这是设置线性方程的方法。

struct Entity
{
    float x1; // Minimum value of X
    float x2; // Maximum value of X
    float vx; // Velocity in X
    // etc.
};

Entity entity1;
Entity entity2;

// Find the interval during which the X-coordinates overlap...

// TODO: Handle the case Entity1.vx == Entity2.vx!!!

// Solve for Entity1.x1 + t * Entity1.vx = Entity2.x2 + t * Entity2.vx
// t * Entity1.vx - t * Entity2.vx = Entity2.x2 - Entity1.x1
// t * (Entity1.vx - Entity2.vx) = Entity2.x2 - Entity1.x1
float timeXa = (Entity2.x2 - Entity1.x1) / (Entity1.vx - Entity2.vx);

// And the other side...
// Entity1.x2 + t * Entity1.vx = Entity2.x1 + t * Entity2.vx
// t * Entity1.vx - t * Entity2.vx = Entity2.x1 - Entity1.x2
// t * (Entity1.vx - Entity2.vx) = Entity2.x1 - Entity1.x2
float timeXb = (Entity2.x1 - Entity1.x2) / (Entity1.vx - Entity2.vx);

float timeXMin = std::min(timeXa, timeXb);
float timeXMax = std::max(timeXa, timeXb);

然后对 Y 和 Z 做同样的事情,并与时间间隔相交。请注意,我可能犯了一些愚蠢的符号错误,并且我没有处理等速情况,这可能会导致除以零。您需要在最终代码中进行一些快速的单元测试,以确保它给出合理的结果。

于 2013-08-05T20:03:32.753 回答