ball reflection inside a circle

Started by
6 comments, last by lrom 16 years, 3 months ago
my first post, i'm a newbie using c++ with a concept question regarding the physics of a pinball playfield. Any suggestions or code snippets on how to compute some of what is described below would be greatly appreciated. I have no code, I can' yet visualize how to do this. The playfield will be a vertical rectangle, having a 180 degree semicircle arc at the top flush with the top and sides (think of a tombstone shape for the play area). The ball is a typical ball with x, y, radius properties and vectors vx, vy. Gravity will be added. The ball will be launched from the right side, and roll into the arc. We know the radius of the playfield arc, so using pythagorean theory I can determine when/where the ball collides with the curved corners but I have no idea how to compute the reflected angle and adjust the vectors to redirect the ball and keep inside the boundaries. thanks!
Advertisement
What you'll want to do is find the plane tangent to the circle at the point the ball collides with the circle. To see why you need this, think of zooming in on the situation. The closer you zoom in on the point of contact, the less the circle looks like a circle, and the more it looks like a plane. If you keep zooming in, the ball will look like it's simply hitting a plane, and this is an easy situation to deal with.

Now, to collide a particle with a plane, we basically want to take the particle's momentum and reflect it around the plane's normal. So really, we don't care much about the plane, just about it's normal vector. In our case, finding the normal vector of this plane is easy, it's just the normalized vector pointing from the point of contact to the center of the circle.
If you want realistic behaviour I suggest using a physics engine as the ball's spin will probably affect things (though if the friction is low then maybe it's not so important...).
Thanks to you both for your replies. Completely realistic behavior will not be necessary, this is just an experiment. I've never used a "physics engine", but it sounds interesting.

If I understand Samith, the line of radius from the center of the arc/circle to the point of collision is the "normal" line, with a perpendicular tangent line being the theoretical reflector. This makes sense, I'm sure I've seen this illustrated somewhere.

The part where we "take the particle's momentum and reflect it around the plane's normal" was tougher to grasp. I presume done with some trig functions using ball.vx/ball.vy to compute the angle? There's probably a shortcut as I would think that there would be a rectangle enclosing that vector to the normal line?

Thanks again!
It's actually very easy.

We know the ball's velocity vector, we'll call that v. And we know the normal vector of this theoretical plane, we'll call that n (I should not, however, that the normal vector is actually the vector from the point of contact to the center of the circle divided by it's length, we must divide by its length to normalize the vector, ie, make it of unit length).

So, to be blunt, the reflected velocity vector v' can be constructed simply:
v' = v - 2*(v.n)*n; // v.n means the dot product of v and n

To understand why this is the equation you'll have to understand the part (v.n)*n as the projection of v onto n. The projection of v onto n can be thought of as like a shadow of vector v onto the vector n. (v.n)*n will be a vector parallel to n. Now, if we take v and subtract (v.n)*n we'll get a vector that is perpendicular to n. If we subtract (v.n)*n again, we'll get v', the reflection of v about n. This is kind of confusing at first, and it really helps if you draw the situation out to see how it works. My explanation is short at best, but a reflection is a pretty standard operation, and there are likely to be plenty of places on the internet that explain it a bit better than I have here, if you're still having trouble.
Thanks for all the help on this Samith, this gives me a good start. I think I have the calculation correct, I'll walk through a simple test in case there are any other newbies following this thread that are as lost as I was (no guarantee though!).

formula:
vresult = vi - (2 * vn * dot(vi, vn))

particle vector vi moving (1, -2) reaches circle boundary. Vector vn from circle center to ball covers (4, -3). I got a result of (-2.2, 0.4)

normalize vn:
vn normalized = (0.8, -0.6)

two times vn:
(0.8 x 2), (-0.6 x 2) = (1.6, -1.2)

dot product of vi & vn
(1 X 0.8) + (-2 X -0.6) = 2

multiply (2*vn) * dotp...
(1.6 x 2, -1.2 x 2) = (3.2, -2.4)

subtract from vi result
(1 - 3.2, -2 - -2.4) = (-2.2, 0.4)

I created a simple vector class to do these calculations based on other code from the net. It's members are doubles for vx and vy. Here are the important bits (functions) from the class:

double vector2::dotProduct(vector2 v)
{
return (vx * v.vx + vy * v.vy);
}

void vector2::normalize()
{
double len = sqrt(vx * vx + vy * vy);
if(len != 0)
{
vx = vx / len;
vy = vy / len;
}
}

In some quick tests with a bouncing ball the reflections looked good but I have coded an error somewhere, as the ball gains speed with each reflection. I didn't have time to debug it yet but it's probably something silly as i wrote it at a mile a minute.

Thanks again for your help. When I get around to inventing the flippers and bumpers I'll probably be back, that should be interesting as well.
That is a great question. What C++ compiler are you using?
Using DJGPP and Allegro. I am fairly new to the compiler and brand new to the Allegro libraries.

This topic is closed to new replies.

Advertisement