# [SOLVED] Bouncing ball with polar coordinates

• 04-21-2009, 03:58 PM
Ypsilon IV
[SOLVED] Bouncing ball with polar coordinates
Hi everyone! I've looked through the forums but still I couldn't find similar problem.
Basically, what I want is:
1. balls bouncing from the "walls"
2. balls bouncing from each other

I have managed to write a function that detects collisions of the balls and changes the speed and directions. Howerver, I have a problem with making balls bouncing from the wall. I want the to hit the wall and then to fly away with the angle which is equal to the angle of the hit. But in my program, they fly away with the same angle after collision with the "walls".
Sorry for the messy code, I still have much work to do (I use Eclipse Europa, each class is in separate file):
Code:

```package test; import java.awt.*; import java.lang.*; public class Ball {         float x, y;         float radius;         float speed;         float Angle;         Color color;         public static Graphics g;                 public Ball (float x, float y, float r, float s, float a, Color c) {                 this.x = x;                 this.y = y;                 this.radius = r;                 this.speed = s;                 System.out.print(a);                 System.out.print("  ");                 this.Angle = (float)Math.toRadians(a);                 if(Angle > 3.14 || Angle < -3.14) {                                         }                 System.out.print(Angle);                 System.out.print("  ");                 this.color = c;         }                 public double getSpeedX() {                 return speed * (float)Math.cos(Angle);                }                 public double getSpeedY() {                 return speed * (float)Math.sin(Angle);         }                 public void move() {                 x += getSpeedX(); y += getSpeedX();                 if((x < radius)) {                         System.out.print("west  ");                         Angle = ((float)(Math.PI) - Math.abs(Angle));                 }                 if((y < radius)) {                         System.out.print("north  ");                         System.out.print(Angle);                         System.out.print("  ");                         //Angle = ((float)(Math.PI)-  Math.abs(Angle));                         float temp = (float)Math.PI / Angle;                         Angle = (temp-1)/temp;                         System.out.print(Angle);                         //System.out.print(Angle);                         //System.out.print("  ");                 }                 if(x > (400 - radius)) {                         System.out.print("east  ");                         Angle = ((float)(Math.PI) - Math.abs(Angle));                 }                 if(y > (400 - radius)) {                         System.out.print("south  ");                         Angle = ((float)(Math.PI) - Math.abs(Angle));                 }         }                 public static boolean collide(Ball b1, Ball b2) {                 float TempX, TempY;                 if(b1.x > b2.x)                         TempX = b1.x - b2.x - 1;                 else                         TempX = b2.x - b1.x - 1;                 if(b1.y > b2.y)                         TempY = b1.y - b2.y - 1;                 else                         TempY = b2.y - b1.y - 1;                                 int dDistance = (int)Math.sqrt((double)(TempX * TempX + TempY * TempY));                 if(dDistance > (int)(b1.radius + b2.radius))                         return false; System.out.print("collision!");                 float Alpha = ((float)Math.atan2(TempY, TempX));                                 float v1P = b1.speed * (float)Math.cos(Alpha - b1.Angle);                 float v1Q = b1.speed * (float)Math.sin(Alpha - b1.Angle);                 float v2P = b2.speed * (float)Math.cos(Alpha - b2.Angle);                 float v2Q = b2.speed * (float)Math.sin(Alpha - b2.Angle);             double v3P = ((b1.radius - b2.radius) * v1P + 2.0f * b2.radius * v2P) / (b1.radius + b2.radius);             double v4P = (2.0f * b1.radius * v1P + (b2.radius - b1.radius) * v2P) / (b1.radius + b2.radius);                     double v3Q = ((b1.radius - b2.radius) * v1Q + 2.0f * b2.radius * v2Q) / (b1.radius + b2.radius);             double v4Q = (2.0f * b1.radius * v1Q + (b2.radius - b1.radius) * v2Q) / (b1.radius + b2.radius);                         b1.speed = (float)Math.sqrt(v3P * v3P + v3Q * v3Q);             b2.speed = (float)Math.sqrt(v4P * v4P + v4Q * v4Q);                         b1.Angle = Alpha - (float)Math.atan2(v3Q, v3P);             b2.Angle = Alpha - (float)Math.atan2(v4Q, v4P);                         return true;         }                 public void paint(Graphics g) {                 g.setColor(color);                 g.fillOval((int)(x - radius), (int)(y - radius), (int)(2*radius), (int)(2*radius));         } }```
Code:

```package test; import java.applet.*; import java.awt.*; public class Go extends Applet implements Runnable {         Thread thread;     Ball ballx;//, bally;//, ballz;     Image dbImage;     Graphics dbg;             public void init() {                 setSize(400,400);       //ballx = new Ball(90, 140, 25, 1, 25, Color.red);         ballx = new Ball(200, 100, 25, 5, 190, Color.red);         // public Ball (float x, float y, float r, float s, float a, Color c)         //bally = new Ball(365, 30, 25, 1, 25, Color.blue);         //bally = new Ball(185, 180, 25, 4, 50, Color.blue);         //ballz = new Ball(355, 350, 25, 3, 50, Color.yellow);         }                 public void start() {                 if (thread == null) {                         thread = new Thread(this);                         thread.start();                 }         }                 public void stop() {                 if (thread != null) {                         thread.stop();                         thread = null;                 }         }                 public void destroy() {                         }                 public void run() {                 Thread.currentThread().setPriority(Thread.MIN_PRIORITY);                 while (true) {                         //ballx.collide(bally);                         //Ball.collide(ballx, bally);                         //Ball.collide(ballx, ballz);                         //Ball.collide(bally, ballz);                         ballx.move();                         //bally.move();                         //ballz.move();                         repaint();                                                 try {                                 thread.sleep(20);                         }                         catch(Exception e) {                                                         }                         Thread.currentThread().setPriority(Thread.MAX_PRIORITY);                 }         }                 public void update(Graphics g) {                 if (dbImage == null) {                         dbImage = createImage (this.getSize().width, this.getSize().height);                         dbg = dbImage.getGraphics ();                         }                 dbg.setColor (getBackground ());                 dbg.fillRect (0, 0, this.getSize().width, this.getSize().height);                 dbg.setColor (getForeground());                 paint (dbg);                 g.drawImage (dbImage, 0, 0, this);                 }                 public void paint(Graphics g) {                 ballx.paint(g);                 //bally.paint(g);                 //ballz.paint(g);         } }```
Code:

```package test; import java.awt.Dimension; import javax.swing.JApplet; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.SwingUtilities; public class NewJApplet extends javax.swing.JApplet {         /**         * Auto-generated main method to display this         * JApplet inside a new JFrame.         */         public static void main(String[] args) {                 SwingUtilities.invokeLater(new Runnable() {                         public void run() {                                 JFrame frame = new JFrame();                                 NewJApplet inst = new NewJApplet();                                 frame.getContentPane().add(inst);                                 ((JComponent)frame.getContentPane()).setPreferredSize(inst.getSize());                                 frame.pack();                                 frame.setVisible(true);                         }                 });         }                 public NewJApplet() {                 super();                 initGUI();         }                 private void initGUI() {                 try {                         setSize(new Dimension(400, 300));                 } catch (Exception e) {                         e.printStackTrace();                 }         } }```
• 04-21-2009, 05:05 PM
emceenugget
personally, i'd rather use direction along each axis for movement instead of messing with angles. makes it all much easier.
• 04-21-2009, 09:15 PM
markw8500
Check out your code here:

Code:

```     public void move() {                 x += getSpeedX(); y += getSpeedX();```
I think you want it to be:

Code:

```     public void move() {                 x += getSpeedX(); y += getSpeedY();```

Then you also want to reverse your Angle when you hit the bounds of your frame...

Code:

``` if (x > (400 - radius )  || x < 0) {             //System.out.print("east  ");             Angle = (((float) (Math.PI) - Math.abs(Angle)))*-1;                     }         if (y > (400 - radius)) {             //System.out.print("south  ");             Angle = (((float) (Math.PI) - Math.abs(Angle)))*-1;                       //System.out.println("Y: "+y);         }```

I multiplied your equasion by "-1" to reverse it...

Overall pretty cool program... It is neat when they collide...
• 04-22-2009, 12:15 AM
Ypsilon IV
markw8500, thank you very very much! It works! :)
• 04-22-2009, 12:19 AM
markw8500
No Prob...