21
\$\begingroup\$

If I have a point which I want to hit at the end or during a parabolic arc, how would I calculate the needed x and y velocity?

\$\endgroup\$
1

4 Answers 4

15
\$\begingroup\$

Parabolic trayectory function is defined as:

   Fx = Vox*t + Ox;
   Fy = -0.5 * g * t * t + Voy*t + Oy;      
  • Known values:

    P: the target point.
    O: the origin point.
    g: gravity.
    t: time needed to impact.
    
  • Unknown values:

    Vo: Initial Velocity
    
  • To calculate 'Vo', we can give values to F function :

    't' = flight time  'duration' 
    'F' = target point 'P'        
    
          (Px-Ox)
    Vox = --------
          duration
    
          Py + 0.5* g * duration * duration - Oy 
    Voy = ---------------------------------------
                     duration
    
  • You can now get all the values to reach the target from the origin giving values to t into the F equation:

     When t = 0         => F == O (Origin)
     When t = duration  => F == P (Target)      
    
\$\endgroup\$
2
  • \$\begingroup\$ great answer. just realize that g is not signed. as g increases, Voy should also increase. \$\endgroup\$
    – milkplus
    Dec 19, 2014 at 19:24
  • \$\begingroup\$ How is t (time needed to impact) known? \$\endgroup\$ Sep 21, 2015 at 6:54
12
\$\begingroup\$

I recently had to solve a similar problem, i came up with two solutions, based on the formula i found on the wikipedia page 'Dan the Man' already mentioned: Trajectory of a projectile

In this solution you acctually need eitherway the launch angle fixed or the x velocity. Y velocity is not needed as we launch the projectile in a specific angle.

Solution 1, launch angle is fixed, calculate the velocity:

g = 9.81; // gravity
x = 49; // target x
y = 0; // target y
o = 45; // launch angle
v = (sqrt(g) * sqrt(x) * sqrt((tan(o)*tan(o))+1)) / sqrt(2 * tan(o) - (2 * g * y) / x); // velocity

Solution 2, velocity is fixed, calculate launch angle:

g = 9.81; // gravity
v = 40; // velocity
x = 42; // target x
y = 0; // target y
s = (v * v * v * v) - g * (g * (x * x) + 2 * y * (v * v)); //substitution
o = atan(((v * v) + sqrt(s)) / (g * x)); // launch angle

In my case this solutions worked quite well.

\$\endgroup\$
3
\$\begingroup\$

If you don't care if it is mathematically correct, only that it looks correct enough, calculate the straight path and make your projectile follow that path, but "push it up" along the normal of that line as a function of it's distance down the line segment, so it rises as it approaches the middle of the segment and falls as it goes away from the middle of the line segment.

You could use a sine wave for this, using the range of degrees from -90 to +90 (where -90 is the left point on the line segment, 90 is right point, and you lerp in the middle), and multiply the result by a constant to scale it up.

If you need the purely correct mathematical / physical answer this won't help. If you don't, this can probably work pretty well for you!

Don't forget, game programming is about using illusions that look correct (and are cheaper to compute), instead of realism.

\$\endgroup\$
3
  • 7
    \$\begingroup\$ Re: "using illusions that look correct (and are cheaper to compute)", I agree in general, but in this case that seems kinda silly given how easy and cheap it is to use the mathematically correct parabolic arc. \$\endgroup\$ Sep 20, 2011 at 0:15
  • 1
    \$\begingroup\$ True that this seems an unnecessary simplification, but I don't think this answer is bad in the bad sense, and it doesn't deserve the downvote (even if it doesn't merit many upvotes). \$\endgroup\$
    – Will
    Sep 20, 2011 at 16:42
  • \$\begingroup\$ Actually if you're going to use a sine wave, it should be 0 to 180 (or 0 to pi in radians) \$\endgroup\$ Aug 13, 2014 at 4:46
2
\$\begingroup\$

If you just need something that is just about right and have a fixed velocity you can use this very simplified method.

distance = to.x - from.x;
angleToPoint = atan2(to.y - from.y, to.x - from.x);
distanceFactor = 1/1000;
angleCorrection = (PI*0.18) * (distance * distanceFactor);
velocity.X = cos(angleToPoint+angleCorrection) * power;
velocity.Y = sin(angleToPoint+angleCorrection) * power;

Distance can be negative but it will still works because the angle depends on the distance too. If the distance is negative the angle that needs to be added is negative too.

You'll need to play around with distanceFactor to find the right value. It depends on the gravity and power of the projectile. It should be near 1 divided through the maximum distance the projectile can cover.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Heads up. When I tried your code, you had cos and sin backwards. I've edited your code so it should be correct. \$\endgroup\$
    – MrValdez
    Oct 3, 2014 at 17:27

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .