linear interpolation in pong

Started by
16 comments, last by JasonL220 18 years, 5 months ago
i have been looking around for solutions to get a good rebound angle, i was given this formulea:

int angle = (45 * (paddle_x - (ball_x + (ball_width/2)) - (paddle_width/2))) / (paddle_width/2);
but the person who posted it was writing it from memory andwas slightly drunk, so would someone please take a look and tell me if it is write.
Advertisement
I couldn't quite figure out that formula, but the idea seems to be something like this:
ball_x = center of ball = ball_sprite_x + ball_width / 2paddle_x = center of paddle = paddle_sprite_x + paddle_width / 2angle = 45 * ((paddle_x - ball_x) / paddle_extent))
The idea being that the ball bounces diagonally at the corners of the paddle, and more and more 'straight up' as it approaches the center. This isn't particularly realistic, but may be ok for a pong game - I don't know. If this is c++, it seems the use of ints rather than floats might cause some problems there. Also, it can sometimes be more useful to deal with velocities in terms of vectors rather than angles.
i was thinking of doing the calulation with floats the casting them to ints when the ballx/bally position is sent to the draw function, i asume that when casting to a int from a float that it round to the nearest whole number, correctly.
Quote:Original post by JasonL220
i asume that when casting to a int from a float that it round to the nearest whole number


Almost. Converting a float to an int truncates. (not to mention throws a warning, and is not very fast. ie look up how your computer stores floats versus ints, and you will see why)

1 == (int)1.234;
2 == (int 2.999;

Rounding takes a little more effort.
so what is there a way of rounding a float without purducing a warning
of course there is :)

go to your MSDN and look for 'floor' and 'ceil'
that wasn't quite what i wanted but is found this would it work?
#define ROUND_FLOAT(x) (((int)(x) + 0.5) < (x)) ? ((int)(x) + 1) : ((int)(x))) and how does it work i've never seen the ? and : operators

edit: ok i see how it works now, but will it throw warnings?

[Edited by - JasonL220 on October 23, 2005 5:59:07 PM]
I don't know about that particular formula you posted, but one method of getting a really good rebound effect is to built an ellipse which approximates the rectangle which specifies the paddle.

The standard equation for an ellipse is

(x-h)^2/a^2 + (y-k)^2/b^2 = 1

where the ordered 2-tuple (h,k) gives the center of the ellipse, and (a,b) gives the half-width and half-height, respectively. If you have your paddle specified by a rectangle given by the 4-tuple R(x,y,w,h), then you can calculate h, k, a and b thusly:

h = (2*R.x + R.w)/2
k = (2*R.y + R.h)/2
a = R.w/2
b = R.h/2

Technically, you could really choose any value of b you want -- the larger the value the more apparent the perturbations to the reflected trajectory of the ball.

Anyway, so you can substitute those into the standard equation for an ellipse, find y' by implicit differentiation, then define the slope of the vector normal to the ellipse at point x as n(x) = -1/y'(x).

So, when the ball hits the paddle, you calculate n(x) and find the normal vector, and then reflect the ball's velocity vector over this normal.

Edit: You can perform rounding on floats with something like this:
template<typename T>int round(const T num) { return floor(num + 0.5); }


Edit2: There is probably a really clever way of finding the normals or tangents of an ellipse which I am not aware of, so if you choose to use the ellipse method it would probably be advantageous to you to google around a little while looking for a simpler method.

[Edited by - nilkn on October 23, 2005 8:43:16 PM]
The above poster is absolutely correct, but the solution may be a little over the top for you. I am going to assume that you are relatively new to programming in c/c++ if you do not know the tertiary operator ( ? : )

First off, the tertiary operator is close to an if/else all in one line. It is handy for situations like the one you posted, where you are defining a macro that makes a decision.

now, back to floor and ceil. These are the only (easy to understand) safe way of converting a float to an int that I know of.

#define ROUND_FLOAT(a) (a%1 < 0.5f ? floor(a) : ceil(a))


yes, you do have the overhead of a modulus, and one function call. However you have eliminated all of your warnings, and are leaving nothing up to the compiler when it comes to converting a float to an int in assembly. I hope this helps.
thanks Days, i'll use that. nilkn I understand the conpect of your idear but dont have any idea how to find the tangent and there for the return angle.

edit: i've have tried to write a test program for the rounding routines but i get this:

test.cpp:6: error: invalid operands of types `const float' and `int' to binary `operator%

in this code:

int ROUND_FLOAT1(const float a)
{
((a%1 < 0.5f) ? (floor(a)) : ceil(a));
return 0;
}

btw i'm compiling with mingw

[Edited by - JasonL220 on October 24, 2005 3:47:33 AM]

This topic is closed to new replies.

Advertisement