PDA

View Full Version : The math of Pong or deflection of an object off a surface



nexusone
04-11-2002, 06:36 AM
There are a few people working on a pong type Opengl games here in this forum, as an example and learning tool for myself I have starting writing a simple pong type program using GLUT.

Currently my ball bounces around the screen with set boundaries and will be deflected by the paddle. My question is on how the ball is deflected by the paddle and walls.

I use a simple check if any x or y-axis of the ball comes to a boundary, change direction that makes all direction changes at a 90-degree angle.

What is the function for the deflection of an object bouncing off a surface?

j
04-11-2002, 06:50 AM
For reflection off the x-axis, negate the y component of the ball's velocity. For reflection off the y-axis, negate the x component of the ball's velocity.


Or do you need the ball to bounce off of a surface that is oriented in any which way?


j

[This message has been edited by j (edited 04-11-2002).]

coredump
04-11-2002, 07:09 PM
you may want to simulate actual physics. the angle of incidence is equal to the angle of refraction.

b

Michael Steinberg
04-11-2002, 08:54 PM
Coredump, it is no actual physics to say that, as it is not exactly true for photons and the like. The probability of this case is the highest though but there exist other possibilities http://www.opengl.org/discussion_boards/ubb/smile.gif

nexusone
04-12-2002, 04:07 AM
I guess my big problem is writing the code so that the object hits at an angle other then 90 degrees.

Wall
|
| / 45 in
|*
| \ 45 out
|

Also on the paddle, I think in the old pong game depending where you hit the paddle you got a varying degree of change in the angle in which the ball bounced off it.

Paddle
| 15
| 45
| 90 degree at center hit...
| 45
| 15


I am sure that I will come up with something, but right now my brain is fried from work....
http://www.opengl.org/discussion_boards/ubb/smile.gif


Originally posted by j:
For reflection off the x-axis, negate the y component of the ball's velocity. For reflection off the y-axis, negate the x component of the ball's velocity.


Or do you need the ball to bounce off of a surface that is oriented in any which way?


j

[This message has been edited by j (edited 04-11-2002).]

04-12-2002, 05:41 AM
i wrote a version of pong a while ago. The angle thing is resolved when you have a (x,y) trajectory, and on collision with a y orientated object (vertical), simply change it to (-x. y), which will cause the ball to bounce back in the opposite direction with an inverse angle like
/
/
/
/
/
\
\
\etc

if you want to change the angle depending on the where the collision with the paddle occurs, simply calculate the position of the ball relative to the center of the paddle. If the ball Y is < paddlemiddle Y then ball y -= some value... or instead of some value try (paddlemiddleY - ballY) or (ballY - paddlemiddleY) if bally > paddlemiddleY.

you see what i mean?

enjoy

Furrage
04-12-2002, 05:48 AM
j is correct (if I understood him right). The easy way to do deflection is:
1) If the ball hits something vertical, reverse it's x value.
2) If the ball hits something horizontal, reverse the y value.

If its not vertical or horizontal you have to use vectors to determine correct deflection. I.e. if the ball is moving with vector v, and the object has normal N, then the deflected vector v1 is given by v1 = v - 2 * dot(v, N) * N. This also works for vertical and horizontal cases.

The paddle is different. Essentially you have to adjust N by a linear or cosine relationship to where it hit the paddle. Give me a little while to do the maths and I'll update the post.

nexusone
04-12-2002, 06:39 AM
Basically that is what I cam currently doing, just looking to improve it.




if (ball_state > 0) // Manage ball if in motion
{
// pos + rate of movement * direction
ball_pos_x = ball_pos_x + 0.5 * ball_direction_x;
ball_pos_y = ball_pos_y + 0.5 * ball_direction_y;
}

if ((ball_pos_x > 490) | | (ball_pos_x < 10)) ball_direction_x = ball_direction_x * -1; // Hit an x screen boundry change direction
if ((ball_pos_y > 240) | | (ball_pos_y < 10)) ball_direction_y = ball_direction_y * -1;




Originally posted by Weazel:
i wrote a version of pong a while ago. The angle thing is resolved when you have a (x,y) trajectory, and on collision with a y orientated object (vertical), simply change it to (-x. y), which will cause the ball to bounce back in the opposite direction with an inverse angle like
/
/
/
/
/
\
\
\etc

if you want to change the angle depending on the where the collision with the paddle occurs, simply calculate the position of the ball relative to the center of the paddle. If the ball Y is < paddlemiddle Y then ball y -= some value... or instead of some value try (paddlemiddleY - ballY) or (ballY - paddlemiddleY) if bally > paddlemiddleY.

you see what i mean?

enjoy

[This message has been edited by nexusone (edited 04-12-2002).]

[This message has been edited by nexusone (edited 04-12-2002).]

[This message has been edited by nexusone (edited 04-12-2002).]

Furrage
04-12-2002, 07:05 AM
Here are two ways to make the ball bounce off the paddle.

Assume paddle has three sections. Left, Middle and Right. If it hits the middle normal horizontal deflection applies. If it hits the left or right then you want skewed deflection.



left mid right
x-------x------x-------x
x1 x2 x3 x4

For shewed deflection you need to determine a value for the deflection axis, N. This is the distance from the closer end over the length of that section.



if (x1 < Ball.x < x2)
Skew = (Ball.x - x1) / (x2 - x1)
else if (x3 < Ball.x < x4)
Skew = (x4 - Ball.x) / (x4 - x3)

1) If you are using a linear relationship this value is used create N as a weighted average between the paddle's normal, Np, and a maximum deflection axis (Nl for left, Nr for right).



if (x1 < Ball.x < x2)
N = Skew * Np + (1 - Skew) * Nl
else if (x3 < Ball.x < x4)
N = Skew * Np + (1 - Skew) * Nr

2) If you are using an angular relationship this value is converted to an angle for the deflection axis, A, between 0 and a maximum angle (+/-Amax for left or right) which is used to create N.



if (x1 < Ball.x < x2)
A = -Amax * Skew
else if (x3 < Ball.x < x4)
A = Amax * Skew
N = (sin(degtorad(A), cos(degtorad(A))

Then use the general deflection code to get the final direction the ball moves in. v is initial velocity of the ball and v1 is the final velocity of the ball.



v1 = v - 2 * dot(v, N) * N

You might also want to create a maximum deflection angle. Otherwise if the ball angle of incidence is large it will still be deflected off screen.