I am trying to do some physics calculations from scratch, and as a result am creating a small bouncing ball example. However, I have some issues getting correct results from my impact physics when the ball bounces on the floor. I have attempted to follow the simple guide on Gamasutra (as referenced by my lecturer) that does impact physics between two balls. This is elastic collisions meaning the energy should be preserved (the ball should keep bouncing). I can cheat but I do want the proper physics calculations of the impact working as I need to use this for more complicated things later.
My current problem is that the ball bounces to a much higher position than it's starting point. I.e the ball starts at a specific position, with a velocity of 0,0,0 and is being effected by gravity. When it hits the floor however, the velocity calculated is much too high, so it bounces much higher (out of the screen) than the point at where it was dropped. It should, I believe, bounce back to the starting position. Here's a small gif showing what's happening.
Here's my current code. Could anyone point me in the right direction? Thanks!
// create sphere radius 3, color red
my_sphere = new Sphere(3, Vector(0.0,0.0,1.0) );
// set position
my_sphere->setDisplacement( Vector(0,50,0) );
// add gravity acceleration
my_sphere->addAcc( Vector(0.0, -9.82, 0.0) );
Physics foce calculation
// changes the objects velocity and position according to acceleration and time
void PhysicsObject::forceStep(float dt) {
this->vel = this->vel + this->acc*dt;
Vector s = this->vel*dt + ( this->acc * (1/2.0f) * pow(dt,2) );
this->displacement = this->displacement + s;
}
Impact physics:
if ( my_sphere->floor_collision() ) {
// floor properties
Vector floor_vel = Vector(1,1,1);
Vector floor_pos = Vector(0,0,0);
// the floor is immovable e.g. mass=infinite
float floor_mass = std::numeric_limits<float>::max();
// Ball properties
Vector ball_vel = my_sphere->getVel();
Vector ball_pos = my_sphere->getDisplacement();
float ball_mass = 1;
Vector n = ball_pos - floor_pos;
n = n.normalize();
float a1 = ball_vel.dotProduct(n);
float a2 = floor_vel.dotProduct(n);
float optimizedP = (2.0 * (a1 - a2)) / (ball_mass + floor_mass);
Vector new_ball_vel = v1-n*optimizedP * floor_mass;
my_sphere->setVel( new_ball_vel );
}