Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.awt.geom.Ellipse2D;
- import java.util.LinkedList;
- import java.util.List;
- public class DummyModel implements IBouncingBallsModel {
- private final double areaWidth;
- private final double areaHeight;
- private Ball small, large;
- public DummyModel(double width, double height) {
- this.areaWidth = width;
- this.areaHeight = height;
- large = new Ball(2, 6, 3, 7, 1.8, 1.8);
- small = new Ball(8, 4.3, -2, 2, 0.4, 0.4);
- }
- public boolean hasCollided(Ball b1, Ball b2){
- // Calculate the relationship to ensure they are moving towards each other
- double xDist = b1.x - b2.x;
- double yDist = b1.y - b2.y;
- double xVelocity = b2.vx - b1.vx;
- double yVelocity = b2.vy - b1.vy;
- /* With these variables we can calculate a relationship
- relationship = (x1 - x2)(vx2 - vx1) + (y1 - y2)(vy2 - vy1)
- (1) (2) (3) (4)
- (1) + Ball 1 is to the right of ball 2
- - Ball 2 is to the right of ball 1
- (2) + Ball 2 is faster than ball 1 (in the x direction)
- - Ball 1 is faster than ball 2 (in the x direction)
- (3) + Ball 1 is above ball 2
- - Ball 2 is above ball 1
- (4) + Ball 2 is faster than ball 1 (in the y direction)
- - Ball 1 is faster than ball 2 (in the Y direction)
- This tells us that if relationship is smaller than or equal to zero there are three possible scenarios:
- 1. The balls are moving away in both x and y direction.
- 2. One ball is moving towards the other in x direction but not in the y direction and the velocity in y is larger than or equal to x
- 3. One ball is moving towards the other in y direction but not in the x direction and the velocity in x is larger than or equal to y
- In these scenarios the balls are not moving towards each other.
- */
- double relationship = xDist*xVelocity + yDist*yVelocity;
- boolean movingTowardsEachOther = relationship > 0;
- // Calculate if they are touching each other
- double ballDistance = getPolarR(b2.x - b1.x, b2.y - b1.y);
- boolean intersecting = ballDistance <= b1.r + b2.r;
- // They can only be considered collided if they are both touching each other and are moving towards each other
- return intersecting && movingTowardsEachOther;
- }
- public void collisionConvert(Ball b1, Ball b2){
- // Calculate variables needed for the calculations
- double pi = Math.PI;
- double m1 = b1.weight, m2 = b2.weight, u1x = b1.vx, u1y = b1.vy, u2x = b2.vx, u2y = b2.vy;
- double phi = getPolarV(b2.x - b1.x, b2.y - b1.y);
- double theta1 = getPolarV(u1x, u1y), theta2 = getPolarV(u2x, u2y);
- double u1 = getPolarR(u1x, u1y), u2 = getPolarR(u2x, u2y);
- // Calculate the rotated velocities
- double u1r = u1 * Math.cos(theta1 - phi);
- double u2r = u2 * Math.cos(theta2 - phi);
- // Calculate the new velocities
- double v1 = (u1r * (m1 - m2) + 2 * m2 * u2r) / (m1 + m2);
- double v2 = (u2r * (m2 - m1) + 2 * m1 * u1r) / (m1 + m2);
- // Divide the new velocities in x and y and add the rotated original velocity
- // (the "remaining" velocity not included in the collision is added)
- b1.vx = v1 * Math.cos(phi) + u1 * Math.sin(theta1 - phi) * Math.cos(phi + pi / 2);
- b1.vy = v1 * Math.sin(phi) + u1 * Math.sin(theta1 - phi) * Math.sin(phi + pi / 2);
- b2.vx = v2 * Math.cos(phi) + u2 * Math.sin(theta2 - phi) * Math.cos(phi + pi / 2);
- b2.vy = v2 * Math.sin(phi) + u2 * Math.sin(theta2 - phi) * Math.sin(phi + pi / 2);
- }
- @Override
- public void tick(double deltaT) {
- ballTick(large, deltaT);
- ballTick(small, deltaT);
- if(hasCollided(small, large)) {
- collisionConvert(small, large);
- small.onGround = false;
- large.onGround = false;
- }
- }
- public boolean wallCollisionX(Ball ball){
- return ball.x <= ball.r || ball.x >= areaWidth - ball.r;
- }
- public boolean wallCollisionY(Ball ball){
- return ball.y <= ball.r || ball.y >= areaHeight - ball.r;
- }
- void ballTick(Ball ball, double deltaT){
- if(wallCollisionX(ball)){
- ball.vx *= -1;
- }
- if(wallCollisionY(ball)){
- ball.vy *= -1;
- if(ball.onGround){
- ball.vy = 0;
- ball.y = ball.r;
- }
- ball.onGround = true;
- }else {
- ball.onGround = false;
- }
- if(!(ball.vy == 0 && ball.y == ball.r))
- ball.vy -= 9.82 * deltaT;
- ball.x += ball.vx * deltaT;
- ball.y += ball.vy * deltaT / 2;
- }
- public double getPolarR(double x, double y){
- return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
- }
- public double getPolarV(double x, double y){
- return Math.atan2(y, x);
- }
- @Override
- public List<Ellipse2D> getBalls() {
- List<Ellipse2D> myBalls = new LinkedList<Ellipse2D>();
- large = new Ball(large);
- small = new Ball(small);
- myBalls.add(large);
- myBalls.add(small);
- return myBalls;
- }
- private class Ball extends Ellipse2D.Double{
- double x, y, vx, vy, r, weight;
- boolean onGround;
- Ball(double x, double y, double vx, double vy, double r, double weight){
- super(x - r, y - r, 2 * r, 2 * r);
- this.x = x;
- this.y = y;
- this.vx = vx;
- this.vy = vy;
- this.r = r;
- this.weight = weight;
- this.onGround = false;
- }
- Ball(Ball ball){
- super(ball.x - ball.r, ball.y - ball.r, 2 * ball.r, 2 * ball.r);
- this.x = ball.x;
- this.y = ball.y;
- this.vx = ball.vx;
- this.vy = ball.vy;
- this.r = ball.r;
- this.weight = ball.weight;
- this.onGround = ball.onGround;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement