views:

399

answers:

2

I'm trying to write a 2D simulation of a ball that bounces off of fixed vertical and horizontal walls. Simulating collisions with the faces of the walls was pretty simple--just negate the X-velocity for a vertical wall or the Y-velocity for a horizontal wall. The problem is that the ball can also collide with the corners of the walls, where a horizontal wall meets with a vertical wall. I have already figured out how to detect when a collision with a corner is occurring. My question is how the ball should react to this collision--that is, how its X and Y velocities will change as a result.

Here's a list of what I already know or know how to find: *The X and Y coordinates of the ball's center during the frame when a collision is detected *The X and Y components of the ball's velocity *The X and Y coordinates of the corner *The angle between the ball's center and the corner *The angle in which the ball is traveling just before the collision *The amount that the ball is overlapping the corner when the collision is detected

I'm guessing that it's best to pretend that the corner is an infinitely small circle, so I can treat a collision between the ball and that circle as if the ball were colliding with a wall that runs tangent to the circles at the point of collision. It seems to me that all I need to do is rotate the coordinate system to line up with this imaginary wall, reverse the X component of the ball's velocity under this system, and rotate the coordinates back to the original system. The problem is that I have no idea how to program this.

By the way, this is an ideal simulation. I'm not taking anything like friction or the ball's rotation into account. I'm using Objective-C, but I'd really just like a general algorithm or some advice. Many thanks if anyone can help!

+2  A: 

As you say you can treat the corner as a circle with infinitely small radius. The normal of the collision plane in this case is given by a unit vector from the contact point to the center of the ball:

float nx = ballX - cornerX;
float ny = ballY - cornerY;
const float length = sqrt(nx * nx + ny * ny);
nx /= length;
ny /= length;

to reflect the velocity vector you do this:

const float projection = velocityX * nx + velocityY * ny;
velocityX = velocityX - 2 * projection * nx;
velocityY = velocityY - 2 * projection * ny;
Andreas Brinck
A: 

If it's a sharp right-angled corner it will act as a retrorefector and bounce it back along the path it came in on. (by sharp I mean without any fillet)

Pete Kirkham