Beginner - Sphere-to-Plane Collision Response

Started by
2 comments, last by Nanook 13 years, 5 months ago
I'm trying to work out a very simple physics system involving spheres and triangle planes. All collision detection is working properly, and sphere-to-sphere collisions look great as long as neither sphere is bumped through a plane during the collision ... anyway ...

I'm getting an odd effect with my sphere-to-plane responses, which is driving me a little bit insane. I've got the equation

NewVelocity = oldVelocity - ( 2*energyCoefficient*planeNormal*( planeNormal.oldVelocity )

from quite a few sources, but the way I'm implementing it in the code must be wrong. I've been tinkering with it for hours upon hours, and I'm not getting anywhere. The only results I get are either sphere completely passing through the plane (i.e. newVelocity == oldVelocity), or the sphere reflecting up and backwards so that it winds up infinitely hopping back and forth between two spots on the plane (strangely, with this setup, fiddling with the energy coefficient has no effect whatsoever). I'm beginning to think the problem might be in my general structure. To wit, that's:

1. At the timestep, update spheres:               a) iterate all spheres and apply gravity               b) iterate all spheres and process collisions          with each sphere: 1. iterate all planes, detect collisions, respond                            2. iterate all spheres, detect collisions, respond     c) iterate all spheres and update position


In a couple of places I've seen it recommended to detect collisions, store collision info in a separate container, and process responses after all collision information is detected. Is this my problem? But it behaves the same way whether there's 1 or hundreds of spheres going!

Here's the code that elicits the strange hopping behavior. Please forgive the bad syntax. My Vector3d class operator overloads don't seem to work when I combine expressions (can you tell I'm a noob?).

void sphereToPlaneCollisions( PhysObj& b ){    for( planeIter pi = allPlanes.begin(); pi != allPlanes.end(); ++pi )        if( sphereToPlaneCollision( b, **pi ) )        {            b.pos = b.lastPos;            b.vel = b.lastVel;            b.lastVel = b.vel;            double speed = b.vel.length();            b.vel.normalize();            // double energyCoefficient = 0.1;                        Vector3d n = (*pi)->getUnitNorm();            Vector3d newVel( b.vel );            b.vel *= -1.0;            double nDotV = n.dot( b.vel );            n *= nDotV;            newVel += n;            newVel.normalize(); // newVel *= speed;            // newVel *= ( 1 + energyCoefficient );            b.vel = newVel;        }}


Thanks for your guidance.

EDIT: By the way, I've tested that the plane normal is being calculated properly.
Advertisement
b.vel = b.lastVel;
b.lastVel = b.vel;
?

newVel.normalize();
b.vel = newVel;
You are setting velocity to a normalized vector here?

I don't remember the formula from the top of my head, but try googling "mirror vector with plane".. You might want to look into calculating an impulse instead..

good luck :)
Wow. Was I overcomplicating that, or what?

I'm all set now. Thanks so much for the tip.
No worries :)

This topic is closed to new replies.

Advertisement