Finding Initial Velocity Given Angle and Destination

Finding Initial Velocity Given Angle and Destination

A physics problem typically involves using a given angle and velocity to determine where a projectile lands. This is all well and good, but when working on a game with projectiles, you already know where it should land and at what angle it should be launched. This article shows the process by which I solved the basic physics equations to take in the desired difference in distance, height, and launch angle to give you the required velocity in return. If you are not interested in the work, you can skip to the solution. Without further ado, here is how I solved the equations.

The Standard Equations

\begin{align}
x\prime &= x + tv\cos\theta\cr
y\prime &= y + tv\sin\theta - \frac{1}{2}gt^2
\end{align}

Rearranging and Replacing

\begin{align}
x\prime - x &= tv\cos\theta\tag{x.1}\cr
d &= tv\cos\theta\label{x.2}\tag{x.2}
\end{align}

\begin{align}
0 &= y - y\prime + tv\sin\theta - \frac{1}{2}gt^2\tag{y.1}\cr
0 &= h + tv\sin\theta - \frac{1}{2}gt^2\label{y.2}\tag{y.2}
\end{align}

To make things more obvious, we will replace the differences with a single variable, namely \(d = x\prime - x\) (where \(d\) is the intended travel distance), and \(h = y - y\prime\) (where \(h\) is how high the projectile starts relative to its ending height).

Eliminating \(t\)ime

For this equation to work, time cannot be a factor. In truth, it does not matter how long the projectile takes to get there, just that we arrive. If you need time later, divide the range by the \(x\) velocity component. Since the \(y\) equation has a quadratic for time, we will solve that one.

Using the condensed height equation in \(\eqref{y.2}\), we can solve using the quadratic formula (and some basic negation cancellation).

\begin{align}
t = \frac{v\sin\theta \pm \sqrt{v^2\sin^2\theta + 2gh}}{g}\label{t}\tag{t}
\end{align}

Since we know that what is coming out of the square root is positive, we can eliminate the possibility of a negative option being the one we ultimately want. The projectile is supposed to be moving forwards after all.

The Heart of the Matter

Now that we have time eliminated from \(\eqref{t}\), we need to plug it in to the \(\eqref{x.2}\) equation.

$$ d = \frac{v\cos\theta}{g}\left[v\sin\theta + \sqrt{v^2\sin^2\theta + 2gh}\right] $$

Then we need to solve that monster for \(v\). We start by moving \(g\) over, and distributing \(v\cos\theta\).

\begin{align}
dg =& v\cos\theta\left[v\sin\theta + \sqrt{v^2\sin^2\theta + 2gh}\right]\nonumber\cr
=& v^2\sin\theta\cos\theta + v\cos\theta\sqrt{v^2\sin^2\theta + 2gh}\nonumber\cr
=& v^2\sin\theta\cos\theta + \sqrt{v^4\sin^2\theta\cos^2\theta + 2ghv^2\cos^2\theta}
\end{align}

We then isolate the square root and square both sides to eliminate it and consolidate common terms.

\begin{align}
dg - v^2\sin\theta\cos\theta &= \sqrt{v^4\sin^2\theta\cos^2\theta + 2ghv^2\cos^2\theta}\cr
d^2g^2& - 2dgv^2\sin\theta\cos\theta + v^4\sin^2\theta\cos^2\theta\cr
&= v^4\sin^2\theta\cos^2\theta + 2ghv^2\cos^2\theta\cr
d^2g^2 - 2dgv^2\sin\theta\cos\theta &= 2ghv^2\cos^2\theta\cr
d^2g^2 &= 2ghv^2\cos^2\theta + 2dgv^2\sin\theta\cos\theta
\end{align}

We continue to eliminate like terms, extract the velocity component, and re-balance.

\begin{align}
d^2g &= 2hv^2\cos^2\theta + 2dv^2\sin\theta\cos\theta\cr
d^2g &= v^2\left(2h\cos^2\theta + 2d\cos\theta\sin\theta\right)\cr
v^2 &= \frac{d^2g}{2h\cos^2\theta + 2d\cos\theta\sin\theta}
\end{align}

Using trig identities, we can simplify the equation and keep like terms.

\begin{align}
v^2 &= \frac{d^2g}{2h\cos^2\theta + d\sin2\theta}\cr
v^2 &= \frac{d^2g}{h\cos2\theta + h + d\sin2\theta}
\end{align}

We are pretty much done here. We just need to take the square root and integrate it into code.

Solution

$$ v = \sqrt{\frac{d^2g}{h\cos2\theta + h + d\sin2\theta}} $$

Where:

\begin{align}
g &= 9.81 \text{(or whatever your gravity is)}\cr
h &= y - y\prime\cr
d &= x\prime - x\cr
&\arctan(\tfrac{h}{d})<\theta<\frac{pi}{2}
\end{align}

Putting it into Code

The code itself is pretty straightforward. Below is an example function that I wrote to handle doing the mathematics of finding the velocity.

// This function determines the required velocity to reach the range at the given height and angle
private float DoTheMath(float distance, float height, float angle)
{
    // Doubled values to make things easier
    float doubleDistance = 2f * distance;
    float doubleAngle = 2f * angle;
    // The lowest angle is a direct shot at an infinite velocity
    float lowestAngle = Mathf.Atan2(height, distance) * 2;

    // If the angle doesn't fall within the (lowestPossible, 90) range, there is no solution
    if (angle >= Mathf.PI || angle <= -lowestAngle) {
        return 0;
    }

    // I figured this equation out after working through the standard physics equations.
    // See: http://plantingcode.net/finding-initial-velocity-given-angle-and-distance/
    return Mathf.Sqrt((9.81f * doubleDistance) / (height * Mathf.Cos(doubleAngle) + height + distance * Mathf.Sin(doubleAngle)));
}
Show Comments