Sign in to follow this  
lazE

collision response

Recommended Posts

Hey, I am trying to setup collision response in a small game that I have written. I was never a very good physics student so I am not sure if I am on the right track at all so I was hoping to get some help...here's what I have so far... 1) get the angle between the two forward vectors. 2) apply a force to the forward vector of the object that was hit (the 2nd object) equal to the cosine of the angle * the force of motion of the 1st object at the time of collision. 3) apply a force to the right vector of the 2nd object equal to the cosine of the angle + 90 * the same force of motion. Not really sure if thats right and I am pretty much clueless about how to the object that caused the collision should respond. thanks in advance ;D

Share this post


Link to post
Share on other sites
I'd advice against using angles, you'll be much better of with vector maths.

what you'll need is, the normal of the collision plane, the velocity of the two objects, the mass of the two objects, and the coefficient of restitution (how much should they bounce off each other).

I kind of explain a simple collsion response sytem based on that here

http://uk.geocities.com/olivier_rebellion/Polycolly.zip

Tutorial4, arcade collision response. The stuff before (polygon collision detection), you can ignore that.

Share this post


Link to post
Share on other sites
Ok...I took a quick look at the code but, I am afraid I just don't know enough to be able to follow it...

Do you think you could explain a little bit more about what you said?

Share this post


Link to post
Share on other sites
basically, it's similar to the reflection in optics.

first, take a single particle hitting a plane.

particle has velocity V, plane as normal N.

the new velocity of the particle after reflection (when it 'bounces' off the plane) is

V -= (2.0f * V.DotProduct(N)) * N;

the particle velocity will be reflected off the plane of collision.

for example, if you have two spheres colliding, the collision plane will be the tangent between the two spheres, which is, simple enough aligned with the positions of the spheres.

now, for two massive objects colliding with each other, they both have velocities, so you have to work in the local space of the collision, where the velocities are relative to each other.

Vcoll = ObjB.Vel - ObjA.Vel;
Vcoll = -(2.0f * Vcoll.DotProduct(Ncoll)) * Ncoll;

so now, the resulting impulse need to be added to the velocities of the objects to make them bounce off each other. you just have to re-distribute the velocity to each objects, to affect their trajectory.

ObjB.Vel += Vcoll * (ObjB.InverseMass / (ObjA.InverseMass * ObjB.InverseMass);
ObjA.Vel -= Vcoll * (ObjA.InverseMass / (ObjA.InverseMass * ObjB.InverseMass);

Say the objects are overlapping by the amount dcoll, there is an additional code I use, which move the objects apart and stop them drifting into each other. Simply push the objects along the normal.

ObjB.Position += Ncoll * (dcoll * 0.5f);
ObjA.Position -= Ncoll * (dcoll * 0.5f);

here is a quick example of two spheres colliding, then bouncing off each other.




struct CSphere
{
Vector Pos;
Vector Vel;
float rad;
float mass;

bool Collide(const CSphere& Sphere, Vector& Ncoll, float& dcoll) const
{
Vector D = Sphere.Pos - Pos;
float d2 = D.DotProduct(D); // distance between the two sphere centre, squared.
float r = rad + Sphere.rad;
float r2 = r * r;
if (d2 > r2)
return false;

float d = sqrt(d2); // distance between sphere centre
dcoll = r - d; // amount of overlap
Ncoll = D / d; // normal of collision plane
return true;
}

bool Bounce(CSphere& Sphere, const Vector& Ncoll, float dcoll)
{
// move spheres away from each other so they stop overlapping
Pos -= Ncoll * (dcoll * 0.3f);
Sphere.Pos += Ncoll * (dcoll * 0.3f);

// impact velocity
Vector Vcoll = Sphere.Vel - Vel;

// impact velocity only along the normal
float vn = Vcoll.DotProduct(Ncoll);

// the spheres are not actually colliding, don;t bounce
// still apply the separation code above, in case.
if (vn > 0.0f) return false;

// generate the necessary impulse to make the spheres
// bounce off each other
Vcoll = -(2.0f * vn) * Ncoll;

// inverse masses
float im1 = 1.0f / mass;
float im2 = 1.0f / Sphere.mass;

// apply the impulse to the spheres
Vel -= Vcoll * im1 / (im1 + im2);
Sphere.Vel += Vcoll * im2 / (im1 + im2);

return true;
}
}





several advantages of doing it that way.
1) you can collide any kind of shapes you want. All you need is to calculate the normal of collision, and amount of overlap.
2) It works for static objects (object with mass = infinity => invmass = 0);
3) it's very simple, very quick. no complicated maths. you only need a bit of vectors. You can do hundreds of spheres colliding with each other, all at the same time.
4) easily extendable, to add friciton, elastic collisions.

it's all in there in the docs. look at tutorial 4, the code above should relate roughly to the pictures in there.

also, I'm pretty sure I got the signs right, but you never know... IN case of problems, ask.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this