Saturday, June 7, 2014

Java elastic collision of two balls

Pseudo elastic collision of two balls in java. Quick and dirty solution to implement elastic collision in java. There is better solution but this can serve good as well. Two balls are moving with different speed. One is heavier then the other, so we expect on collision the lighter ball to pick up some speed. Also if smaller ball hit bigger ball with certain amount of speed we expect bigger ball to pick some speed as well.

Here is ball class:


  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package realball;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;

/**
 *
 * @author Anak1n
 */
public class ball {

    private float x;
    private float y;
    private float diametar;
    Color color;
    private double xSpeed;
    private double ySpeed;

    public ball(float x, float y, float diameter, Color color) {
        this.x = x;
        this.y = y;

        this.diametar = diameter;
        this.color = color;
    }

    public void draw(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        Ellipse2D.Double circle = new Ellipse2D.Double(getX() - getDiametar() / 2, getY() - getDiametar() / 2, getDiametar(), getDiametar());
        g2d.fill(circle);
    }

    public void move() {
        setX((float) (getX() + getxSpeed()));

        if (getX() - getDiametar() / 2 < 0) {
            setX(getDiametar() / 2);
            setxSpeed(-getxSpeed());
        } else if (getX() + getDiametar() / 2 > 390) {
            setxSpeed(-getxSpeed());
        }

        setY((float) (getY() + getySpeed()));

        if (getY() - getDiametar() / 2 < 0) {
            setySpeed(-getySpeed());
        } else if (getY() + getDiametar() / 2 > 360) {
            setY(360 - getDiametar() / 2);
            setySpeed(-getySpeed());
        }
    }

    /**
     * @return the xSpeed
     */
    public double getxSpeed() {
        return xSpeed;
    }

    /**
     * @param xSpeed the xSpeed to set
     */
    public void setxSpeed(double xSpeed) {
        this.xSpeed = xSpeed;
    }

    /**
     * @return the ySpeed
     */
    public double getySpeed() {
        return ySpeed;
    }

    /**
     * @param ySpeed the ySpeed to set
     */
    public void setySpeed(double ySpeed) {
        this.ySpeed = ySpeed;
    }

    /**
     * @return the x
     */
    public float getX() {
        return x;
    }

    /**
     * @param x the x to set
     */
    public void setX(float x) {
        this.x = x;
    }

    /**
     * @return the y
     */
    public float getY() {
        return y;
    }

    /**
     * @param y the y to set
     */
    public void setY(float y) {
        this.y = y;
    }

    /**
     * @return the diametar
     */
    public float getDiametar() {
        return diametar;
    }

    /**
     * @param diameter
     */
    public void setDiametar(float diameter) {
        this.diametar = diameter;
    }
}


gui class:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package realball;

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;

/**
 *
 * @author Anak1n
 */
public class gui extends JPanel implements Runnable {

    ball b1;
    boolean going = true;

    Thread animator;
    ball b2;
    double deltaX;
    double deltaY;
    double distance;

    public gui() {
        b1 = new ball(50, 80, 40, Color.red);
        b1.setX(50);
        b1.setY(80);
        b1.setxSpeed(4);
        b1.setySpeed(2);

        b2 = new ball(50, 80, 70, Color.red);
        b2.setX(150);
        b2.setY(80);
        b2.setxSpeed(4);
        b2.setySpeed(2);

        

        animator = new Thread(this);
        animator.start();

    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        b1.draw(g);
        b2.draw(g);
        g.setColor(Color.red);

        // draw center of circle
        g.fillOval((int) b1.getX() - 5, (int) b1.getY() - 5, 10, 10);
        g.fillOval((int) b2.getX() - 5, (int) b2.getY() - 5, 10, 10);

    }

    @Override
    public void run() {
        while (going) {
            b1.move();
            b2.move();

            checkCollision();

            repaint();

            try {
                Thread.sleep(20);
            } catch (InterruptedException ex) {
            }
        }
    }

    public void checkCollision() {

        deltaX = Math.abs(b1.getX() - b2.getX());
        deltaY = Math.abs(b1.getY() - b2.getY());
        distance = deltaX * deltaX + deltaY * deltaY;
        
        if (distance < (b1.getDiametar() / 2 + b2.getDiametar() / 2) * (b1.getDiametar() / 2 + b2.getDiametar() / 2)) {

            double newxSpeed1 = (b1.getxSpeed() * (4 - 7) + (2 * 7 * b2.getxSpeed())) / 11;

            double newxSpeed2 = (b2.getxSpeed() * (7 - 4) + (2 * 4 * b1.getxSpeed())) / 11;

            double newySpeed1 = (b1.getySpeed() * (4 - 7) + (2 * 7 * b2.getySpeed())) / 11;

            double newySpeed2 = (b2.getySpeed() * (7 - 4) + (2 * 4 * b1.getySpeed())) / 11;

            b2.setxSpeed(newxSpeed2);
            b2.setySpeed(newySpeed2);
            b1.setxSpeed(newxSpeed1);
            b1.setySpeed(newySpeed1);

        }
    }

}


main class:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import javax.swing.JFrame;

/**
 *
 * @author Anak1n
 */
public class RealBall {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
       JFrame frame = new JFrame ();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        gui balls = new gui ();
        frame.setSize(400,400);
        frame.add(balls);
        frame.setVisible(true);
    }
    
}


If you want to improve this collision I would suggest calculating angle of impact and new direction after impact.

Video:

2 comments:

  1. Hard Rock Hotel & Casino, Las Vegas - Mapyro
    Hotels 고양 출장샵 near Hard Rock Hotel & 김천 출장샵 Casino, Las Vegas - Mapyro Hotels The 군산 출장샵 Hard 진주 출장마사지 Rock Hotel & Casino, which opened in 2005 as a temporary resort 창원 출장마사지 for a

    ReplyDelete
  2. Merkur 37C Safety Razor Review – Merkur 37C
    The Merkur 37c 도레미시디 출장샵 is an excellent short handled DE 토토 사이트 safety razor. It is more https://deccasino.com/review/merit-casino/ suitable for both heavy and non-slip hands https://jancasino.com/review/merit-casino/ and is therefore titanium metal trim a great option for experienced

    ReplyDelete