Sign in to follow this  
biyangdo

Beginner - Sphere-to-Plane Collision Response

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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 :)

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