collision response

Started by
2 comments, last by oliii 19 years, 4 months ago
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
"We are what we repeatedly do. Excellence, therefore, is not an act, but a habit."-Aristotle
Advertisement
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.

Everything is better with Metal.

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?
"We are what we repeatedly do. Excellence, therefore, is not an act, but a habit."-Aristotle
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.

Everything is better with Metal.

This topic is closed to new replies.

Advertisement