DRiFTy
DRiFTy

Reputation: 11369

Circle and Rectangle Collision Android

I have a ball bouncing on my screen and there is a static rectangle that it can collide with and should bounce off of. I have already figured out how to test if the ball has collided with the rectangle and that works great. Now I need to determine which side of the rectangle that the ball has hit. I am currently trying this code (which works for testing the four sides but seems to have problems with the corners)...

if(Math.abs(ball.centerY-boundingBox.top) < ball.radius) {
    // Hit the top

}
else if(Math.abs(ball.centerY-boundingBox.bottom) < ball.radius) {
    // Hit the bottom

}
else if(Math.abs(ball.centerX-boundingBox.left) < ball.radius) {
    // Hit the left

}
else if(Math.abs(ball.centerX-boundingBox.right) < ball.radius) {
    // Hit the right

}

... Does anyone have any ideas how I can improve this? Or come up with a better solution for that matter?

I just basically need to determine which side a circle has hit on a rectangle after they collide. And I have already figured out how to test whether they collide or not.

Thanks!

Upvotes: 0

Views: 3122

Answers (1)

Tommy
Tommy

Reputation: 100622

It presumably doesn't work for corners because when the ball hits a corner, it hits two sides simultaneously. And if you're looking to make it bounce accurately, the relevant normal vector is that from the centre of the ball to the corner, which is going to be some diagonal between horizontal and vertical.

Assuming you always detect overlap while the centre of the ball is outside the rectangle, what you probably want to do is something like:

// is the ball above the box?
if(Math.abs(ball.ballCenterY-boundingBox.top) < ball.radius)
{
    if(ball.ballCentreX >= boundingBox.left)
    {
         if(ball.ballCentreY <= boundingBox.right)
         {
             // ball hit the top edge
         }
         else
         {
             // ball hit the top right corner
         }
    }
    else
    {
        // hit top left corner
    }
}

A better test — to handle both inside and outside collisions — would be to find distance to the closest point on each side, pick the smallest distance, then if closest point is a corner then its a corner collision, otherwise it's a side collision.

Upvotes: 1

Related Questions