Archived

This topic is now archived and is closed to further replies.

Bouncing Algorithm

This topic is 6576 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Just a simple algorithm: If you are dealing with a box aligned on the X and Y axises, just invert the relevant component of the velocity when the object impacts the wall. For example, when it hits the top or bottom wall, invert the Y component, and when it hits the left or right wall, invert the X component.

Anything more complex will deal with calculations against the surface normal of the wall at the impact point.

- Splat

Share this post


Link to post
Share on other sites
Hi Splat,

I want an algorithm that will respond to the ball hitting the paddle or targets on the middle of the board. And I want it to be realistic. For example, what do I do when the ball hits the extreme left half of the rectangular paddle, I don't think you can just inverse the x and y velocities. Please include some code samples.

Share this post


Link to post
Share on other sites
Well one thing that you can do is to break the paddle up into portions, by that I mean that you make an array or something to store the three "paddles" i.e. instead of storing the paddle coordinates like:
(or if in only 1d then just use the top line of my example)

+------------+
| |
+------------+

on the +'s you break the one paddle up into three paddles like so.

+--+------+--+
| | | |
+--+------+--+

so you actually make three paddles, then when you test for the ball hitting the paddle you can deflect it normally for the middle section and deflect it on a greater angle when it hits the side sections.

I am assuming that is what you want right?

And with this example you can split it up into more than three sections and use as many as you want.

What do you think Splat & mmarvi???

------------------
-Dom
Visit - http://www.eisa.net.au/~sdgrab/index.html


[This message has been edited by Dæmin (edited December 01, 1999).]

Share this post


Link to post
Share on other sites
First off, the idea presented above is what most people use for Breakout-style games and hockey games, so for simplicity sake I would recommend that. Otherwise, you will need to use the surface normal at the impact point to figure out the resulting velocity vector for the puck. It's generally covered in Physics courses. I have no drawings to help you, you will have to search around for info or find an old Physics book. Also, if you want to take into account friction, rotational speed on the puck and the current movement of the paddle you need to do some more calculations. However, it's likely you really don't want this much reality, and that the above algorithm (with a little tweaking) will work fine for your purposes.

- Splat

Share this post


Link to post
Share on other sites
Hi Dom,

Thanks for your advice, it sounds like a good idea. However, at what angle should I deflect the ball when it hits the "side paddles", i.e. not the middle paddle? If possible, include some code samples.

Share this post


Link to post
Share on other sites
How about using a degree-based direction on the specific object?
Ok, the calculations may be quite slow, and i don't know if this tip will achieve anything, but i'll post it anyway..

By using a degree-based direction on the "ball" (G, don't even know the english word on the hockey thing, so i'll use ball instead,ok?), the bounce algorithm is quite easy.

Suppose you put a huge cylinder on the ice, and a ball bounces towards it:

//Ball movement algorightm
ball.x = cos(ball.dir)*ball.speed;
ball.y = sin(ball.dir)*ball.speed;

//a funcion that determines if the ball is //"inside" the cylinder
if (In_Cylinder(ball.x,ball.y))
{

//Check the angle at the point on the //cylinder where the ball boundces
float cylinderdir = atan(ball.y/ball.x);

//The difference between the ball direction //and the cylinder point direction
float dirchange = ball.dir-cylinder.dir;

//Set the new angle
ball.dir = cylinder.dir-dirchange;

//This whole example may be complemented //with some "%"-functions also
}


there.
The way i see it, the main problem is finding a good algorithm for the
InCylinder() - function. It's easy making this function, but hard to make it go fast.

Please do not use this specific example in your program. I just got a brainstorm while reading this post, and i thought it would be something to think of.

Share this post


Link to post
Share on other sites
Well for the 3 section paddle I would suggest that when the end paddles are hit then you reflect the puck off as normal but then you add 45 degrees in the direction that where the segment is (I.e. Right segment, then ad 45 degrees to the right) to your output puck vector.

I.e.


1)
/ <- Incoming vector
/
+--+----+--+

2)
\ <- Outgoing vector
\
+--+----+--+

3) +45 degrees right
\ | <- Final vector (roughly)
\|
+--+----+--+


In the first picture we have the incoming vector, the second is the unmodified outgoing vector, then in the third picture we have the "final" outgoing vector with the 45 degrees added to it.

Do you roughly get what I mean?

And if you wanted to add more segments then you could alter the angles that are added(taken away in some cases) to get a different effect.

------------------
-Dom
Visit - http://www.eisa.net.au/~sdgrab/index.html


[This message has been edited by Dæmin (edited December 02, 1999).]

Share this post


Link to post
Share on other sites
for a 2d bouncing algorithm, you need only two things. a) a line segment that describes the surface off of which the puck will be bouncing(x1,y1) and (x2,y2), and b) the x,y velocity of the puck. (its a PUCK, not a ball)

1. calculate the angle in which the linesegment goes.

it doesnt matter if you go from x1,y1 to x2,y2 or the other way. it JUST DOESNT MATTER.

dont use atan, use atan2, to avoid division by 0

surfaceangle=atan2(x2-x1,y2-y1)

2. get the normal of the surface angle

surfacenormalangle=surfaceangle+pi/2

(you can also subtract pi/2, it doesnt really matter)


3. get the incoming angle of the ball

again, using atan2

incomingangle=atan2(x,y)
//x and y are the x and y components of the balls velocity

4. reverse the incoming angle(we are going to be reflecting this angle across the normal angle, so we need it outgoing)

incomingangle+=pi

(or -=pi if you like)

5. calculate the outgoing angle

outgoingangle=incomingangle+(surfacenormalangle-incomingangle)*2

6. adjust the x,y of the ball's speed

mag=sqrt(x*x+y*y)

x=mag*cos(outgoingangle)
y=mag*sin(outgoingangle)

Share this post


Link to post
Share on other sites
TANSTAAFL,

Thanks for your algorithm. However, I'm a little confused about what the variables represent. Will this particular algorithm slow down the game any? Do you have any code samples on this algorithm?

Share this post


Link to post
Share on other sites
no, i dont have any code samples for that algorithm. its a purely mathematical algo.

however, the cost shouldnt be too bad... two calls to atan2 and one call each to cos and sin, with a few floating point mults and adds.

Share this post


Link to post
Share on other sites
TANSTAAFL,

Can you thoroughly explain what what the variables x1, y1, x2, and y2 stand for? Does "pi" stand for 3.141592....?

By the way, does anyone have a good pixel-perfect collision detection algorithm that is compatible with CDX and MSVC++ 5.0?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I think that x1,y1, are the start of the line, and x2,y2, and the end of the line, and yeah, bet dats pi.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
In reply to your question about perfect pixel collision detection, I don't know where you can find one.

However, if you are detecting collision between two circles all you have to do is find the distance between the centers of the two. If that distance is less than or equal two the sum of the two radii then they are in contact.

Distance Formula:
D = sqrt( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) )
(derived from a^2 + b^2 = c^2)

Also, about the angle of incidence of the puck on the paddle. If your paddle is perfectly rectangular then the puck will bounce off in the same direction irregardless where it hits the paddle.

Share this post


Link to post
Share on other sites
I am writing a simple 2-D table hockey game using CDX and MSVC 5.0 Professional, and I want some code that can demonstrate a realistic bouncing ball algorithm that I can use in such a game.

Share this post


Link to post
Share on other sites
I had to figure out the same algorithm when I was making a simple pong game. I split the paddle into 7 different sections, and I made each one 9 pixels each. When the ball's y coordinate was greater than the lower board's y coordinate and the ball's x coordinate was equal to any x coordinate of the board it was about to make contact with I specified new speed variables. I did this by making the game add the x and y speed to the x and y coordinates of the ball.
Example:

Here is the coordinate plane I used:
0,0----------------50,0 (X axis)
|
|
|
|
|
0,50
(Y axis)

Paddle is the left most coordinate of the
paddle. To get the sections, all I had to
was add 9 for each section, because each section was 9 pixels long.
ball_velocity_x is the speed of the ball on the x axis
ball_velocity_y is the speed of the ball on the y axis

paddle_left = paddle + 18;

// Left of paddle, for lower paddle
if ((ball_x >= paddle && ball_x <= paddle_left) && (ball_y > paddle_y))
{
ball_velocity_x = .4;
ball_velocity_y = 2.4;
}

Here are the angles I used for my paddle:
Left = ball_velocity_x = -.4
ball_veloctiy_y = -2.4
Left Center = ball_velocity_x = -1
ball_velocity_y = -1
Center = ball_velocity_x = 0
ball_velocity_y = -1
Right Center = ball_velocity_x = 1
ball_velocity_y = -1
Right = ball_velocity_x = .4
ball_velocity_y = -2.4

For the upper paddle I just reversed those velocity settings. I didn't include the centermost left and right areas because I forgot what they were and I don't have my program to look at right now.

If you have any questions about what I just posted please ask. I hope that helped you.

Share this post


Link to post
Share on other sites