Sign in to follow this  
Defeatist

Table Tennis Ball Arc

Recommended Posts

I'm making a table tennis game in 3D and I have trouble with calculating the arc of my table tennis ball.

I have the following:
-a table tennis ball "Ball" with a position coordinate and a velocity vector
-the coordinate where the ball collides with a racket
-the Ball's target coordinate

This automatically happens:
for every frame, I add Gravity G to the Ball's velocity vector. The balls position is incremented by the velocity vector. Then, the velocity gets multiplied by an air friction constant F.

I want to to calculate the outgoing velocity vector(after collision) that is required to get the ball on target. How do I do this?

Ok I put some extra time into it and i couldn't get it to work. I'm using the following article:
http://en.wikipedia.org/wiki/Trajectory_of_a_projectile#Angle_.CE.B8_required_to_hit_coordinate_.28x.2Cy.29

This is what I have so far:

        private Vector3 CalculateOutgoingVector(Ball Ball, Vector3 target)
{
Vector3 t = new Vector3(target.X - Ball.position.X, 0.0f, target.Z - Ball.position.Z);

float g = Configuration.GRAVITY * (float)Game.State.gametime.ElapsedGameTime.TotalSeconds; // This is 1/60, the framerate is locked
float v = Ball.velocity.Length();

double component = Math.Sqrt(v*v*v*v - g*(g*t.X*t.X + 2*(target.Y - Ball.position.Y)*v*v));
double angle0 = Math.Atan(((v*v) + component) / (g*t.X));
//double angle1 = Math.Atan(((v*v) - component) / (g*t.X));

t.Normalize();

t *= (float)Math.Cos(angle0);
t.Y = (float)Math.Sin(angle0);

return t * v;
}





Somehow angle0 is always -1.5707 radians and angle1 = +1.5707, launching the ball into the table or straight up in the air respectively
Note that I'm using XNA's coordinate system (Y up).

[Edited by - Defeatist on October 5, 2010 4:44:34 PM]

Share this post


Link to post
Share on other sites
Maybe because t.X==0.0 or g==0?
If I understand correctly the formula, your code should be like this:
private Vector3 CalculateOutgoingVector(Ball Ball, Vector3 target)
{
Vector3 t = new Vector3(target.X - Ball.position.X, 0.0f, target.Z - Ball.position.Z);

float g = Configuration.GRAVITY;//Why multiply it by elapsed time? g is constant
float v = Ball.velocity.Length();

double component = Math.Sqrt(v*v*v*v - g*(g*(t.X*t.X + t.Z*t.Z) + 2*(target.Y - Ball.position.Y)*v*v));//should use t not just t.X
double angle0 = Math.Atan(((v*v) + component) / (g*t.Length()));//you could also use atan2
//double angle1 = Math.Atan(((v*v) - component) / (g*t.Length()));

t.Normalize();

t *= (float)Math.Cos(angle0);
t.Y = (float)Math.Sin(angle0);

return t * v;
}

Note that this formula doesn't take into account air friction. To take into account friction (and Magnus effect, wich makes ping pong a more interresting game :) I would go for a Monte-Carlo approache, but maybe there are better ones.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this