/* Copyright 2010 Christian Matt
*
* This file is part of PonkOut.
*
* PonkOut is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PonkOut is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PonkOut. If not, see <http://www.gnu.org/licenses/>.
*/
package ponkOut.logic;
import org.lwjgl.util.vector.Vector2f;
/**
* Collision between two balls
*/
public class BallCollision extends Collision {
private Ball ball2;
public BallCollision(float time, Ball ball1, Ball ball2) {
super(time, ball1);
this.ball2 = ball2;
}
@Override
public void apply() {
// if one ball is wall ball, just reflect other ball
if (!ball.isMovable() || !ball2.isMovable()) {
if (!ball.isMovable()) {
reflectAtBall(ball2, ball.getPosition());
} else {
reflectAtBall(ball, ball2.getPosition());
}
} else {
// elastic collision
// decompose the velocities of the balls into a component in the
// direction of the line between the balls (normal) and a
// perpendicular one (tangential)
// apply a central elastic collision to the normal components
// and let the tangential components be unchanged
Vector2f v1 = ball.getVelocity();
Vector2f v2 = ball2.getVelocity();
float m1 = ball.getMass();
float m2 = ball2.getMass();
Vector2f n = new Vector2f();
Vector2f.sub(ball2.getPosition(), ball.getPosition(), 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 v1_t = Vector2f.dot(v1, t);
float v2_t = Vector2f.dot(v2, t);
// calculate new velocities in normal direction
float u1_n = (m1 * v1_n - m2 * v1_n + 2.0f * m2 * v2_n) / (m1 + m2);
float u2_n = (m2 * v2_n - m1 * v2_n + 2.0f * m1 * v1_n) / (m1 + m2);
// transform to x- and y-components
Vector2f n1 = new Vector2f(n.x, n.y);
Vector2f t1 = new Vector2f(t.x, t.y);
Vector2f n2 = new Vector2f(n.x, n.y);
Vector2f t2 = new Vector2f(t.x, t.y);
Vector2f.add((Vector2f) n1.scale(u1_n), (Vector2f) t1.scale(v1_t), v1);
Vector2f.add((Vector2f) n2.scale(u2_n), (Vector2f) t2.scale(v2_t), v2);
ball.setVelocity(v1);
ball2.setVelocity(v2);
}
// detach attached balls after collision
ball.detach();
ball2.detach();
}
}