这就是我将如何做到的。首先,找出两个框的 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 做同样的事情,并与时间间隔相交。请注意,我可能犯了一些愚蠢的符号错误,并且我没有处理等速情况,这可能会导致除以零。您需要在最终代码中进行一些快速的单元测试,以确保它给出合理的结果。