Search code examples
javacollision

Java "simple" Bumping Ball/Collision exercise


I read through some other similar q/a on this, but need help specifically on how to make the balls bounce off each other.

  • this program has the user input the speed of the redraw and the number of balls.
  • I can get them to bounce off of the walls just fine.

Here's my code:

(import ArgsProcessor; import sedgewick.StdDraw;)

public static void main(String[] args) {
    ArgsProcessor ap = new ArgsProcessor(args);
    //request from user - get refresh rate and number of balls
    int pause = ap.nextInt("Enter pause time:");
    int numBalls = ap.nextInt("How many balls will you put into play?");

    // set the scale of the coordinate system

    StdDraw.setXscale(-1.0, 1.0);
    StdDraw.setYscale(-1.0, 1.0);

    // initial values
    int[] balls = new int[numBalls];
    double[] positionX = new double[numBalls];
    double[] positionY = new double[numBalls];
    double[] velocityX = new double[numBalls];
    double[] velocityY = new double[numBalls];
    double[] radius = new double[numBalls];
    double distance = 0;

    for (int i = 0; i < numBalls; ++i) {
        balls[i] = numBalls;
        positionX[i] = Math.random();
        positionY[i] = Math.random();
        velocityX[i] = Math.random() * .01;
        velocityY[i] = Math.random() * .01;
        radius[i] = 0.05;
    }

    while (true) {
        // clear the background - draw before since it is on the bottom
        StdDraw.setPenColor(StdDraw.GRAY);
        StdDraw.filledSquare(0, 0, 1.0);

        // bounce off wall according to law of elastic collision
        for (int i = 0; i < numBalls; ++i) {

            if (Math.abs(positionX[i] + velocityX[i]) > 1.0 - radius[i]) {
                velocityX[i] = -velocityX[i];
            }
            if (Math.abs(positionY[i] + velocityY[i]) > 1.0 - radius[i]) {
                velocityY[i] = -velocityY[i];
            }
            positionX[i] = positionX[i] + velocityX[i];
            positionY[i] = positionY[i] + velocityY[i];

        //figure out the distance between
        //if balliradius + balliradius >= distance between, then reverse direction
        for (int j = 0; j < numBalls; ++j){//create a for loop

            distance = Math.sqrt(Math.pow(positionX[i] - positionX[i], 2) + Math.pow(positionY[i] - positionY[i], 2)); 

            if (distance <= radius[i] + radius[i]){ //if distance between two balls has them touching/overlapping, change direction
                positionX[i] = -positionX[i] - velocityX[i];
                positionY[i] = -positionY[i] - velocityY[i];
            } //if balliradius + balliradius < distance between, then keep moving
            // update position
            positionX[i] = positionX[i] + velocityX[i];
            positionY[i] = positionY[i] + velocityY[i]; 

            // draw ball on the screen
            StdDraw.setPenColor(StdDraw.BLUE);
            StdDraw.filledCircle(positionX[i], positionY[i], radius[i]);
        }
        // display and pause for 20 ms
        StdDraw.show(pause);
    }

    }
}

}


Solution

  • To begin with, your test for distance should involve two objects, not just one (as it is, the distance will always be zero) note the use of position*[j]:

    distance = Math.sqrt(Math.pow(positionX[i] - positionX[j], 2) + Math.pow(positionY[i] - positionY[j], 2));
    

    Your bounce calculation is also mistaken. For the simplest possible bounce, just undo the latest velocity adjustment, then reverse the signs of the velocity components (again, you need to access both objects, not just one, note radius[j]):

    if (distance <= radius[i] + radius[j]){ //if distance between two balls has them touching/overlapping, change direction
        // undo last velocity update; now the balls aren't overlapping anymore
        positionX[i] = positionX[i] - velocityX[i] ;
        positionY[i] = positionY[i] - velocityY[i] ;
        positionX[j] = positionX[j] - velocityX[j] ;
        positionY[j] = positionY[j] - velocityY[j] ;
        // now reverse all velocity components
        velocityX[i] = -velocityX[i] ;
        velocityY[i] = -velocityY[i] ;
        velocityX[j] = -velocityX[j] ;
        velocityY[j] = -velocityY[j] ;
        }