@Override
public void apply() {
if (!ball.isMovable()) {
// collision with WallBall - stop paddle
paddle.setVelocity(new Vector2f(0.0f, 0.0f));
// stop attached ball
if (paddle.isBallAttached()) {
GameBall attachedBall = paddle.getAttachedBall();
attachedBall.setVelocity(new Vector2f(0.0f, 0.0f));
}
} else { // ball is movable
Vector2f hemispherePos;
hemispherePos = paddle.getHemispherePosition(hemispherePlace);
// if paddle is not movable, reflect ball at hemisphere
if (!paddle.isMovable())
reflectAtBall(ball, hemispherePos);
else {
// ball and paddle are movable
// decompose the velocities of the balls into a component in the
// direction of the line between the balls (normal) and a
// perpendicular one (tangential)
Vector2f v1 = paddle.getVelocity();
Vector2f v2 = ball.getVelocity();
float m1 = paddle.getMass();
float m2 = ball.getMass();
Vector2f n = new Vector2f();
Vector2f.sub(ball.getPosition(), paddle.getHemispherePosition(hemispherePlace), n);
n.normalise();
Vector2f t = new Vector2f(n.y, -n.x);
float v1_n = Vector2f.dot(v1, n);
float v2_n = Vector2f.dot(v2, n);
float v2_t = Vector2f.dot(v2, t);
float u2_n;
if (v1_n * v2_n <= 0.0f || Math.abs(v1_n) < Math.abs(v2_n)) {
// directions are different or ball hits paddle
// reflect ball and add some momentum of paddle to ball
u2_n = 2.0f * m1 / (m1 + m2) * v1_n - v2_n;
// stop paddle if directions are different
if (v1_n * v2_n <= 0.0f)
paddle.setVelocity(new Vector2f(0.0f, 0.0f));
} else {
// directions are the same and paddle hits ball
// add some momentum of paddle to ball
u2_n = 2.0f * m1 / (m1 + m2) * v1_n + v2_n;
}
// tangential components are not changed
// transform to x- and y-components
Vector2f n2 = new Vector2f(n.x, n.y);
Vector2f t2 = new Vector2f(t.x, t.y);
Vector2f.add((Vector2f) n2.scale(u2_n), (Vector2f) t2.scale(v2_t), v2);
ball.setVelocity(v2);
}
// detach ball after collision