1

I am developing a collision prediction system (language is really irrevelant here) and I am looking for a way to predict collision of two objects' hitboxes after a given time. The variables I have are:

  • 1st entity
  • 2nd entity
  • 1st and 2nd entity Maximum and Minimum XYZ of the entity's bounding box (the "highest" corner and the "lowest" corner)
  • 1st and 2nd entity velocity (we assume its constant)
  • Time

What I have tried so far was calculating the plausable entity position after given time then based on that calculating the hitboxes max and min positions for both entities and checking if for these positions collision happened. The way I did it consisted of very many loops and was incredibly inefficient, though I didn't use any math formula since I have not found one.

There is one on StackOverflow, but for 2D collision prediction and you can find it here.

I would like someone to help me extend this to 3D space.

Community
  • 1
  • 1
Kamil Solecki
  • 1,106
  • 20
  • 34

1 Answers1

3

Here's how I would do it. First, find the interval in time during which the X-coordinates of the two boxes overlap. You can do this by solving two linear equations in t, representing the times when the X-coordinates are just touching:

  • Minimum X of entity 1 at time t = Maximum X of entity 2 at time t
  • Maximum X of entity 1 at time t = Minimum X of entity 2 at time t

Let me know if you want help setting that part up!

Now, solve the same problem for the Y-coordinates. If the interval for Y doesn't intersect the interval for X, the boxes don't collide. If the intervals do intersect, take the intersection and keep going.

Solve the problem for the Z-coordinates to get another interval. If the interval for Z doesn't intersect the interval for X and Y, the boxes don't collide. If the intervals do intersect, take the intersection.

Now you have an interval in time [t1, t2] that represents all points in time when all three coordinates of the boxes overlap -- in other words, all points in time when the boxes overlap! So t1 is the point in time when they collide.

(Another approach would be to replace the hitboxes with ellipsoids and solve a quadratic equation like in the other StackOverflow thread. However, the math is actually harder in that case. Using axis-aligned boxes means you can break down the problem into each coordinate independently and stick to linear equations.)

Edit: By request, here's how to set up the linear equations.

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);

Then do the same thing for Y and Z, and intersect the time intervals. Note that I may have made some silly sign errors, and I didn't handle the equal-velocity case, which can cause a division by zero. You'll want to throw some quick unit tests at the final code to make sure that it gives reasonable results.

Chris Culter
  • 4,470
  • 2
  • 15
  • 30
  • Sorry, Ive been on holiday ;) – Kamil Solecki Aug 18 '13 at 10:27
  • Could you please help me with the linear equations? – Kamil Solecki Aug 18 '13 at 10:28
  • @KamilSolecki Yes, this code is only for axis-aligned boxes. If you want to test for collisions between two boxes with different orientations, that's a harder problem. – Chris Culter Aug 26 '13 at 23:24
  • Also, this wont work if the objects are already in collision on any axis, right? – Kamil Solecki Aug 27 '13 at 04:45
  • 1
    @KamilSolecki I'm not totally sure what you're asking. Let's say that the time interval representing the collision is [tMin, tMax]. If the present moment is represented by t=0, and the boxes are presently overlapping, then tMin < 0 < tMax. If the boxes have not yet collided, but they are on course to collide in the future, then 0 < tMin < tMax. – Chris Culter Aug 27 '13 at 05:12