Skip to main content
GameDev.net gamedev.net
🔒 Locked

Collision prediction

Started by TimChan Feb 17, 2007 at 10:01 PM 5 replies 2.1k views
Original Post
TimChan
TimChan
I'm working on the algorithm for event-driven collision detection. The problem is described below: Assume there are two circles in a 2D space. Given their positions, velocities and accelerations, find when do they collide. If the return value i.e. the time is negative, they won't collide. If the time is zero, they're overlapping or touching. With the use of some circle's properties and the Cosine Rule, my current algorithm can tackle this problem only if the two circles have no accelerations. The problem become much more complicated or maybe impossible to solve when acceleration is taken into consider. Could someone help, please?
TheAdmiral
TheAdmiral
How many degrees of freedom do the circles have, in terms of temporal derivatives of space? If the circles may accelerate arbitrarily at any moment, then the system is nondeterministic, and the calculation is impossible. If, however, the circles are restricted to having constant acceleration, then you're left with a quadratic equation to solve.
Generalising this, if dns/dtn is constant, then you must solve a polynomial equation of degree n.

A huge consideration is as to how accurately you need to solve. If the calculation is only performed when the circles are separated by some distance of a given magnitude, then you should pick an appropriate level of approximation to give results within a tolerable error-margin. The situation is exactly that of approximation of a continuous curve by Taylor expansion: it is your duty to choose an appropriate n.

So I guess what I'm asking is how varied is the motion of the circles and how accurate you want your results to be.

Be aware that any polynomial above linear order may have multiple roots, and working out how to pick the right one will be a real pain. I recommend you stick with the linear situation unless you truly need to do otherwise.

Admiral
Ring3 Circus - Diary of a programmer, journal of a hacker.
oliii
oliii
it's not that complicated if you use, say Euler integration and vector maths.

1) P(t) = P1 + V1 * t + 0.5 * A1 * t^2
2) Q(t) = P2 + V2 * t + 0.5 * A2 * t^2

and at time of collision t,

3) [P(t) - Q(t)]^2 = (r1 + r1)^2


in 3) you replace P(t) and Q(t) by their respective equations.

so you develop, and you get, I believe some 4th order equstion to solve. that caon be solved using root solvers. There will be a number of solutions, between 0 up to 4. You usually pick up the first positive as your time of collision (if there is one).
Everything is better with Metal.
TimChan
TimChan
Thanks so much.

Solving a quartic equation is really bothering...Anyway I'd post the algorithm once it works.
oliii
oliii
Note that, if the acceleration is the same (gravity only), they will cancel each other out.
Everything is better with Metal.
TimChan
TimChan
Oops

demo download

The algorithm works perfectly except colliding object is too small. Below is the major part of it.
float World::PredictCollision(RigidBody &_a, RigidBody &_b, float _min_distance) {	Vector2D displacement = _a.Position - _b.Position;	if(displacement.GetLength() <= _min_distance) return 0;	// Overlapping or touching		Vector2D velocity = _a.Velocity - _b.Velocity;	Vector2D acceleration = _a.Force*_a.InverseMass - _b.Force*_b.InverseMass;	if(velocity.GetLength() == 0 && acceleration.GetLength() == 0) return -1;	// Relatively stationary		float a = displacement.X, b = velocity.X, c = acceleration.X/2;	float x = displacement.Y, y = velocity.Y, z = acceleration.Y/2;	float time;	if(c == 0 && z == 0) {		float t1, t2;		if(!solve_quadric(b*b + y*y, 2*(a*b + x*y), a*a + x*x - _min_distance*_min_distance, t1, t2)) return -1;		time = t1;		if(t2 < t1 && t2 >= 0) time = t2;	} else {		float t1, t2, t3, t4;		if(!solve_quartic(c*c+z*z, 2*b*c + 2*y*z, 2*a*c+b*b + 2*x*z+y*y, 2*a*b + 2*x*y, a*a + x*x - _min_distance*_min_distance, t1, t2, t3, t4)) return -1;		time = t1;		if(t2 < time && t2 >= 0) time = t2;		if(t3 < time && t3 >= 0) time = t3;		if(t4 < time && t4 >= 0) time = t4;	}	return time;}


[Edited by - TimChan on February 21, 2007 5:53:41 PM]
oliii
oliii
Cool. The algo should pretty much work. It is possible there is some floating point innacuracies, or you got some of the parameters wrong. In what way does it fail?

Another way to do it is to use sub-sampling. That is, split the delta time into smaller chunks, and do a linear or static test between the time intervals. Once you found a collision, you can then refine the interval further, until you are within a tolerance (object distance threshold, intersection depth).
Everything is better with Metal.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.