I read through some other similar q/a on this, but need help specifically on how to make the balls bounce off each other.
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);
}
}
}
}
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] ;
}