const Scalar e(1);
+ const Vector normal(na.Direction());
+
const Vector va(a.LinearVelocity());
const Vector vb(b.LinearVelocity());
const Scalar wa(a.AngularVelocity());
const Vector vbp(b.VelocityAt(na.Origin()));
const Vector vab = vap - vbp;
+ const Vector restitutionVAB((-(1 + e)) * vab);
+
const Vector rap90((na.Origin() - a.Origin()).Rotate90());
const Vector rbp90((na.Origin() - b.Origin()).Rotate90());
- const Scalar ia(a.Mass());
+ const Scalar ia(a.Mass()); // inertia equals mass? probably not
const Scalar ib(b.Mass());
+ const Scalar aInverseMass(1.0 / a.Mass());
+ const Scalar bInverseMass(1.0 / b.Mass());
+
const Scalar rap90dotN(rap90.Dot(na.Direction()));
const Scalar rbp90dotN(rbp90.Dot(na.Direction()));
+ const Scalar aRotationalPart((rap90dotN * rap90dotN) / ia);
+ const Scalar bRotationalPart((rbp90dotN * rbp90dotN) / ib);
+
const Scalar j(
- (((-(1 + e)) * vab).Dot(na.Direction()))
- / (na.Direction().Dot(na.Direction() * ((1.0 / a.Mass()) + (1.0 / b.Mass())))
- + ((rap90dotN * rap90dotN) / ia)
- + ((rbp90dotN * rbp90dotN) / ib) ));
+ restitutionVAB.Dot(normal)
+ / (normal.Dot(normal * (aInverseMass + bInverseMass))
+ + aRotationalPart
+ + bRotationalPart ));
- const Vector va2(va + ((j / a.Mass()) * na.Direction()));
- const Vector vb2(vb - ((j / b.Mass()) * na.Direction()));
- const Scalar wa2(wa + ((rap90.Dot(j * na.Direction())) / ia));
- const Scalar wb2(wb - ((rbp90.Dot(j * na.Direction())) / ib));
+ const Vector va2(va + (j / a.Mass()) * normal);
+ const Vector vb2(vb - (j / b.Mass()) * normal);
+ const Scalar wa2(wa + rap90.Dot(j * normal) / ia);
+ const Scalar wb2(wb - rbp90.Dot(j * normal) / ib);
a.linearVelocity = va2;
a.angularVelocity = wa2;
void Entity::InfInfCollisionResponse(Entity &a, const Ray &na, Entity &b) {
// If both elements are standing still or both are moving, move them away
// from each other. Otherwise, move the moving one.
+ // This will keep the paddle from bouncing off the wall at infinite velocity.
if ((a.linearVelocity == Vector() && b.linearVelocity == Vector())
|| (a.linearVelocity != Vector() && b.linearVelocity != Vector())) {
a.Translate(na.Direction());
, worldWidth(800)
, worldHeight(480)
, ball(10)
-, secondBall(7)
-, thirdBall(5)
+, secondBall(8)
+, thirdBall(7)
, leftPaddle(10, 100)
, rightPaddle(10, 100)
, topWall(800, 10)
}
ball.Translate(Entity::Vector(400, 240));
- ball.Accelerate(Entity::Vector(180, 180));
+ ball.Accelerate(Entity::Vector(180, 180), 0);
// ball.SetMaxVelocity(500.0f);
secondBall.Translate(Entity::Vector(300, 240));
- secondBall.Accelerate(Entity::Vector(-50, -50), 1);
+ secondBall.Accelerate(Entity::Vector(-50, -50), -3);
// secondBall.SetMaxVelocity(600.0f);
thirdBall.Translate(Entity::Vector(200, 440));
- thirdBall.Accelerate(Entity::Vector(60, 40));
+ thirdBall.Accelerate(Entity::Vector(60, 40), 3);
leftPaddle.Translate(Entity::Vector(5, 200));
rightPaddle.Translate(Entity::Vector(795, 280));