
3d pong physics
hey all, i've been working on a 3d version of pong, and i've got everything in and working correctly other than the reflection. is there a site, or can someone break down on the CORRECT way to do this? i have some ghetto ideas on how to make it work, but since this is my first 3d graphics game (my first real graphics anything actually) i want to do it right. i'm working with vectors and i've already assigned normal vectors to all the walls. (6 of them)
what do i need to do now?
thanks

Taking the picture below as a guideline (note, the ball is travelling up, to the right, and into the screen).
Whenever a collision with a wall occurs, you'd just multiply the normal with the current velocity vector on the ball to get the new velocity (same speed, but bouncing off).
It'd be up to you to figure out which normal vectors go where (which it sounds like you might have that done already) and if you want to increase the speed off a bounce, you'd change the 1 to a 1.2 or something so that the new speed would be larger (Or use numbers between 0 and 1 to slow the ball down).
In the example below, if the ball is travelling right (+X) and hits the right wall, multiplying the vectors would result in X becoming negative (hence travelling left) while keeping everything else the same because you multiplied the rest by 1.
Not totally sure if this is what you were looking for, but if it is, then I hope it helps.

i was thinking of doing it EXACTLY that way, but then i was told that the normal vectors were more like
<1,0,0> <1,0,0> and so on.
an a funny note, that room looks EXACTLY like my room that was created for the game !! :)

Hehe, well that point about normal vectors is true, I shouldn't call what I have normal vectors...more of...directionthatyouwanttheballtobounce vectors? :)
A normal is perpendicular to the plane, so a normal in this case (with the axis as it is), would look like the form you had (with zeros). Since, for instance, going strictly perpendicular to the right wall, you're travelling left (X = 1), you're not travelling up (Y = 0), and you're not travelling into the screen (Z = 0). But if you're gonna follow this method, then it's not exactly the vectors you need, but the directions I had (the same ones you were wanting to use) :)

You can do this using the dot product. Move the problem to 2D first.
Here is a solution in 2D:
Code:
struct ball
{
int x;
int y;
int lastx;
int lasty;
float xinc;
float yinc;
};
void ComputeReflection2D(ball &_theball)
{
//Form a right triangle based on last position
//Since we know we have hit a wall our current location is the basis for the right
//triangle
//The X vector or base of triangle
int diffx=_theball.lastx_theball.x;
//The Y vector or height of triangle
int diffy=_theball.lasty_theball.y;
//The length of the hypotenuse  the path we just took
int length=sqrt((diffx*diffx)+(diffy*diffy));
//The new vectors normalized
_theball.xinc=(float)(diffx/length);
_theball.yinc=(float)(diffy/length);
//Update last position for next hit calculation
_theball.lastx=_theball.x;
_theball.lasty=_theball.y;
}
Notice that the above equation knows nothing about the wall. In 2D you really don't need to unless you want slanted walls which then you must take the normal into account. But for simple boxed in playing field you can assume that if you have entered the above function...you have hit a wall.
Quickly you will notice that this can also be accomplished by using cos(). Essentially that is what the code is doing, if I wrote it right. It's been sometime since I approached this problem.
But in 3D this is a very simple calculation and could be used in 2D as well as long as Z was always assumed to be 1.0f.
Here is the formula:
Arccos(theta)=N dot V
Or the arccos of theta is equal to the magnitude of the dot product of the normal to the plane and the vector in question. We need the magnitude because we want this to be normalized.
So the angle between two vectors in 3D can be computed by taking the arccos of the dot product of the two vectors (magnitude for nonunit vectors).
Since you know the normal and you know the vector of the ball you can compute the reflection angle quite easily.
The vector for the ball is the current position, but it might have to be computed by:
ball.vector=ball.posball.lastpos;
Just simply using ball.pos will only work if your world is centered at 0,0,0  which it should be. If the ball is moving to the left that would mean that x would be less than 0 which would make the formula work correctly.
This should work for your needs.
Code:
void ComputeReflection3D(Vector3 &NormalVector,Vector3 &BallVector,Vector3 &BallVelocityVector)
{
//Normalize the BallVector
Vector3 nrmBallVector=Vector3Normalize(BallVector);
//Compute dot product
float dot=Vector3Dot(NormalVector,nrmBallVector);
//Now based on dot product compute new BallVelocityVectors
...
}
Again if this doesn't work exactly as coded I apologize. I did get perfect reflections working in my pong game but that was ages ago.

I'm not sure if bubba really explained it 100%, so I'm just going to repost the equation for doing this.
You've got:
The Normal vector (the vector the wall hit, in your case it can be something like <1, 0, 0> but can also be something like <.7071,0,.7071> just as long as it has a magnitude of 1 unit )
You have your ball's velocity BallVelocity.
To compute the reflected vector you reverse the normal component of the ball's velocity, BallVelocityNormal. There are a bunch of ways of doing this, but without getting into harder equations that deal with things like coefficient of restitution I can show you an easy way, and the only other equation to keep track of is the component of the ball's velocity which is perpendicular to the normal.
BallVelocityNormal = Normal * DotProduct(BallVelocity, Normal)
BallVelocityPerpendicular = BallVelocity  BallVelocityNormal
Now you compute the reflected velocity:
BallVelocity = BallVelocityPerpendicular + (BallVelocityNormal * 1)
and there, that will do it for you. Here is a function I use for doing this, i.e I use it to help compute frustum planes ( I get the right frustum plane, but to get the left frustum plane without having to extract it from OpenGL matrices, then normalize it, I instead just reflected it around the view vector)
Code:
Vector3 Mirror(Vector3 *a, Vector3 *axis)
{
Vector3 parallel = *a  (*axis * DotProduct(a,axis));
return *a  (parallel * 2);
}
edit
I've got to be at a math class then I've got some stuff for a few hours to do but I can draw pictures showing what each step corresponds to.
edit
I also want to point out that these equations only work for what is called a perfectly elastic collision, in which the relative velocities of the objects remains contant. In reality, the angle of incidence is NOT equal to the angle of reflection for real objects. Actually, the only case where this is exactly true is with photons and subatomic particles.

Actually I was going to leave the last bit as an exercise in research for the poster, but I'm glad you posted the rest anyhow.