#### Howdy, Stranger!

We are about to switch to a new forum software. Until then we have removed the registration on this forum.

# How can i get the ball to bounce properly

edited February 2018

Hello! Im trying to get the ball to bounce off the center circle and the edges of the canvas. I've been successful with the edges but i'm having some issues with the circle in the center. Cant figure out how to get the ball to bounce off naturally then right back to where it was. I see that examples that are somewhat similar to this use vectors. I do not want to use vectors because i am very new to programming and haven't been taught how to use them. I would like to figure this out using trig but don't know how to approach it

Tagged:

• please don't post duplicates

• ``````   if (dist(ballX,ballY,centerX,centerY) < (DIAM/2) + (BALL_DIAMETER/2)) {
ballSpeedX = -ballSpeedX;
ballSpeedY = -ballSpeedY;
}
``````

so you're just reversing BOTH directions if the small ball hits the circle. this isn't what you want.

you need to treat it as if it's hit a wall at a tangent to the circle at the point of contact. here's a tutorial:

http://ericleong.me/research/circle-circle/#static-circle-collision

• I couldn't do it

I also think there are minor errors on the tutorial page of eric

``````final int DIAM = 200;
final int BALL_DIAMETER = 15;

float centerX, centerY;

float ballX, ballY;
float ballSpeedX = 3, ballSpeedY = 2;

// -------------------------------------------------------------------

void setup() {
size( 500, 500 );
ballX = 120.0;
ballY = 40.0;

centerX = width/2;
centerY = height/2;
}

void draw() {

background( 128 );

fill(#ff5954);
ellipse(centerX, centerY, DIAM, DIAM);

fill(255);
ellipse( ballX, ballY, BALL_DIAMETER, BALL_DIAMETER );

moveBall();
}

// -------------------------------------------------------------------

void moveBall() {
changeSpeedOnWall();
changeSpeedOnCenterCircle();

ballX = ballX + ballSpeedX;
ballY = ballY + ballSpeedY;
}

void changeSpeedOnWall() {
if ( ballX < BALL_DIAMETER/2 ) {
ballSpeedX = abs(ballSpeedX);//always pos
}

if ( ballX > width-BALL_DIAMETER/2 ) {
ballSpeedX = -abs(ballSpeedX);//always neg
}

// -----

if ( ballY < BALL_DIAMETER/2 ) {
ballSpeedY = abs(ballSpeedY);//always pos
}

if (ballY > height-BALL_DIAMETER/2 ) {
ballSpeedY = -abs(ballSpeedY);//always neg
}
}//func

void changeSpeedOnCenterCircle() {

PVector circle1= new PVector(ballX, ballY);
PVector circle2= new PVector(centerX, centerY);

PVector d = closestpointonline(circle1.x, circle1.y,
circle1.x + ballSpeedX, circle1.y + ballSpeedY, circle2.x, circle2.y);

double closestdistsq = Math.pow( circle2.x - d.x, 2) + Math.pow(circle2.y - d.y, 2 ) ;
if (closestdistsq <= Math.pow(BALL_DIAMETER/2 + DIAM/2, 2)) {
// a collision has occurred

double backdist = Math.sqrt(Math.pow(BALL_DIAMETER/2 + DIAM/2, 2) - closestdistsq);
double movementvectorlength = Math.sqrt(Math.pow(ballSpeedX, 2) + Math.pow(ballSpeedX, 2));
double c_x = d.x - backdist * (ballSpeedX / movementvectorlength);
double c_y = d.y - backdist * (ballSpeedY / movementvectorlength);

double collisiondist = Math.sqrt(Math.pow(circle2.x - c_x, 2) + Math.pow(circle2.y - c_y, 2));
double n_x = (circle2.x - c_x) / collisiondist;
double n_y = (circle2.y - c_y) / collisiondist;

double circle1mass=12;
double circle2mass=1000;

double p = 2 * (ballSpeedX * n_x + ballSpeedY * n_y) /
(circle1mass + circle2mass);

double w_x = ballSpeedX - p * circle1mass * n_x - p * circle2mass * n_x;
double w_y = ballSpeedY - p * circle1mass * n_y - p * circle2mass * n_y;

ballSpeedX=(float)w_x;
ballSpeedY=(float)w_y;
} else {
// no collision has occurred
}//else
//
}

PVector closestpointonline(float lx1, float ly1,
float lx2, float ly2,
float x0, float y0) {
float A1 = ly2 - ly1;
float B1 = lx1 - lx2;
double C1 = (ly2 - ly1)*lx1 + (lx1 - lx2)*ly1;
double C2 = -B1*x0 + A1*y0;
double det = A1*A1 - -B1*B1;
double cx = 0;
double cy = 0;
if (det != 0) {
cx = (float)((A1*C1 - B1*C2)/det);
cy = (float)((A1*C2 - -B1*C1)/det);
} else {
cx = x0;
cy = y0;
}
return new PVector((float)(cx), (float)(cy));
}
``````
• Watch your integer division with BALL DIAMETER / 2

• thanks!

i think it occurs in 10 places