This site uses strictly necessary cookies. More Information

X- Home /

# Trajectory of a projectile formula. Does anyone know maths?

I found this handy page on wikipedia: http://en.wikipedia.org/wiki/Trajectory_of_a_projectile

In there is this formula:

To hit a target at range x and altitude y when fired from (0,0) and with initial velocity v the required angle(s) of launch are:

I gave it my best shot trying to convert this to code, but frankly it's way beyond my math abilities. It sort of works at long ranges, then goes crazy at short ranges. Here's my wack at it:

```
function CalculateProjectileFiringSolution2() {
var targetTransform = target.transform.position;
var barrelTransform = barrel.transform.position;
```

```
```

```
var y = targetTransform.y - barrelTransform.y;
targetTransform.y = barrelTransform.y = 0;
var x = (targetTransform - barrelTransform).magnitude;
var v = projectileSpeed;
var g = Physics.gravity.y;
var sqrt = (v*v*v*v) - (g * (g * (x*x) + 2 * y * (v*v)));
if (sqrt < 0) {
Debug.Log("No Solution");
return 0;
}
sqrt = Mathf.Sqrt(sqrt);
var calculatedAnglePos = Mathf.Atan(((v*v) + sqrt) / (g*x));
var calculatedAngleNeg = Mathf.Atan(((v*v) - sqrt) / (g*x));
return calculatedAnglePos * Mathf.Rad2Deg;
```

}

Can anyone help me out?

EDIT: Updated per suggestions. EDIT AGAIN: Works now.

You could or even should use Atan2. It's a bit saver and calculates the right quadrant (returns a value between [-Pi,Pi] ). Take a look at http://en.wikipedia.org/wiki/Atan2 And of course: http://unity3d.com/support/documentation/ScriptReference/$$anonymous$$athf.Atan2.html

Can you maybe put up your final code for those searching for a similar solution?

Sorry, I edited the question with the working code but that was probably somewhat unclear. I answered with my most up-to-date code including the other functions I ended up needing.

i am having problem getting above function work. can someone help? I posted a separate question here http://answers.unity3d.com/questions/633171/trajectory-of-a-projectile-formula-get-the-same.html

**Answer** by taoa
·
Feb 24, 2011 at 10:22 AM

This formula considers you shoot your projectile from (0,0), which means in your case that you must subtract your barrel position from your target position:

var y = targetTransform.y - barrelTransform.y; var x = targetTransform.x - barrelTransform.x;

Also, for the love of all that's worthy, do not EVER use Mathf.Pow(n,2) when all you want to do is n*n! Pow is a powerful (bwahaha) function that can take a float value as a second parameter, don't waste it on integer powers, as it's way more expensive that a n*n (even a n*n*n*n*n...).

If to_sqrt is <0 before processing it's square root, then it means there is no solution with real numbers, the velocity is insufficient to reach the desired position, so your gameplay code must handle that situation somehow (start at least with a Debug.Log). But do that BEFORE you carry on with your calculation of the angle. You can now drop the Mathf.Abs() part of Mathf.Sqrt(Mathf.Abs(to_sqrt)).

You don't handle the +/- part of the equation properly: there is either 0 (we covered it), 1 (special case where the use or + or - doesn't matter, same result), or two possible solutions to this equation, each given by using either + or -. They will both be correct, so it's up to you to choose which one. I suggest you toss a coin. Or you could simulate one, see if your projectile hits something on the way, then choose the other one if it's better. Your call.

The rest of your code seems fine to me. Except calculatedAngle * 90.0f. I have no idea what the hell you're trying to do here ^^

Best of luck!

Thanks for the response. I updated per your suggestions but it still isn't working. The numbers it returns are in the area of +- 2 or lower so it's always pointing almost exactly straight ahead, regardless of projectile speed.

Nevermind. Atan returns radians. I knew it would be something stupid. Thanks again for all your help. :)

i am having problem getting above function work. can someone help? I posted a separate question here http://answers.unity3d.com/questions/633171/trajectory-of-a-projectile-formula-get-the-same.html do you know why this is happening?

**Answer** by Patyrn
·
Mar 14, 2011 at 11:52 PM

As requested the final code I'm using for my projectile stuff:

```
float CalculateMaximumRange() {
float g = Physics.gravity.y;
float y = origin.position.y;
float v = projectileSpeed;
float a = 45 * Mathf.Deg2Rad;
```

```
```

```
float vSin = v * Mathf.Cos(a);
float vCos = v * Mathf.Sin(a);
float sqrt = Mathf.Sqrt(vSin * vSin + 2 * g * y);
return Mathf.Abs((vSin / g) * (vCos + sqrt));
```

}

float CalculateProjectileFiringSolution() {
Vector3 targetTransform = target.position;
Vector3 barrelTransform = gunMuzzlePoint.position;

```
float y = barrelTransform.y - targetTransform.y;
targetTransform.y = barrelTransform.y = 0;
float x = (targetTransform - barrelTransform).magnitude;
float v = projectileSpeed;
float g = Physics.gravity.y;
float sqrt = (v*v*v*v) - (g * (g * (x*x) + 2 * y * (v*v)));
// Not enough range
if (sqrt < 0) {
haveFiringSolution = false;
return 0.0f;
}
haveFiringSolution = true;
sqrt = Mathf.Sqrt(sqrt);
// DirectFire chooses the low trajectory, otherwise high trajectory.
if (directFire) {
return Mathf.Atan(((v*v) - sqrt) / (g*x));
} else {
return Mathf.Atan(((v*v) + sqrt) / (g*x));
}
```

}

float CalculateFlightTime(float angle) {
Vector3 targetTransform = target.position;
Vector3 barrelTransform = gunMuzzlePoint.position;

```
float x = (targetTransform - barrelTransform).magnitude;
float v = projectileSpeed;
angle = angle == 0 ? 45 : angle;
float time = x / (v * Mathf.Cos(angle * Mathf.Deg2Rad));
return time * .7f;
```

}

Sorry for being a bit dim, but once you have all 3 floats from the methods - how do you use the values to gain motion? I couldn't find a simple enough equation on the wiki page to piece it all together! Thanks for posting the code though!

**Answer** by Arowx
·
Dec 11, 2012 at 10:00 PM

Minor correction you are calculating the value x as the magnitude of the vector this will only give accurate results when the height difference is near zero.

You need to calculate x as the horizontal distance only e.g.

```
float y = (barrelTransform.y - targetTransform.y);
//targetTransform.y = barrelTransform.y = 0;
float xx = targetTransform.x - barrelTransform.x;
float xz = targetTransform.z - barrelTransform.z;
float x = Mathf.Sqrt(xx * xx + xz * xz);
```

**Answer** by petrucio
·
Jul 03, 2019 at 04:03 AM

Putting it all together with proper formatting, less noise, and @Arowx 's fix:

```
bool CalculateThrowAngle(Vector3 from, Vector3 to, float speed, out float angle)
{
float xx = to.x - from.x;
float xz = to.z - from.z;
float x = Mathf.Sqrt(xx * xx + xz * xz);
float y = from.y - to.y;
float v = speed;
float g = Physics.gravity.y;
float sqrt = (v*v*v*v) - (g * (g * (x*x) + 2 * y * (v*v)));
// Not enough range
if (sqrt < 0)
{
angle = 0.0f;
return false;
}
angle = Mathf.Atan(((v*v) - Mathf.Sqrt(sqrt)) / (g*x));
return true;
}
```

Usage:

```
float throwAngle;
if (CalculateThrowAngle(thing.position, at.position, maxSpeed, out throwAngle))
{
Vector3 throwDirection = (at.position - thing.position);
throwDirection.y = 0;
throwDirection = Vector3.RotateTowards(throwDirection, Vector3.up, throwAngle, throwAngle).normalized;
}
rigidbody.velocity = throwDirection * maxSpeed;
```

In action:

(yellow = line to target, red = calculated throw direction, green = path taken. Falls a tiny bit short because of drag, which is fine in my case)

### Your answer

### Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.