This site uses strictly necessary cookies. More Information

X- Home /

# Math Genius NEEDED! Algorithm problem with parabola

Hi all, I am trying to make a targeting system with an artillery turret in which there is a set distance, velocity, and gravity acceleration. This targeting system is supposed to calculate the angle in which the turret should fire at to hit the target. I am having some trouble as it is either undershooting or overshooting the target, and am wondering if I have the ratios of real world values like Unity velocity to Real World velocity mixed up or if the equation is wrong. Here is my code:

```
public class test : MonoBehaviour {
public float angle;
public float g = Physics.gravity.y;
public float v = 1f;
public float d;
public Transform firePoint;
public Transform target;
public TestAAT3 obj;
// Use this for initialization
void Start () {
obj = FindObjectOfType<TestAAT3>();
}
// Update is called once per frame
void Update () {
if (Input.GetKeyDown(KeyCode.Alpha1))
{
CalculateAngle();
}
}
//d = distance between firepoint and target
//g = gravitational acceleration
//v = given velocity
//angle = theta
public void CalculateAngle()
{
d = Vector3.Distance(firePoint.position, target.position);
angle = (1/2) * Mathf.Asin((g * d) / (Mathf.Pow(v_, 2)));
Debug.Log(d);
obj.Fire(d);
}
}
```

Any and ALL help is appreciated. I've looked at wikipedia, khan academy videos, etc. Nothing helps!

Your angle seems to be calculated correctly, unless the firePoint and target are in different elevations (different z values). The formula you use is correct, but only for objects of the same elevation. $$anonymous$$aybe the problem is with your obj.Fire function?

**Answer** by Bunny83
·
Jul 22, 2017 at 08:54 PM

Well first of all "g" should be the value of the acceleration. This should be positive. There is no direction information in a single value. You seem to use the y component of the Physics gravity vector which is usually negative.

Next thing is the formula you use only works when both your firePoint as well as your target are on the exact same height. Also keep in mind when you rely on Unity's physics engine for the actual simulation that this assumes no drag at all.

You also need to check if the term inside ASin is not lower than "-1" or greater than "1", In that case the target can't be reached at all. Also ASin would return a NaN in that case.

If the height of the two points can be different you have to use this one instead. Of course here a similar check has to be done. You can only reach the target when the root has a real value (i.e. the value inside the root has to be 0 or positive). If the root is a complex root the target can't be reached,

Finally what do you actually pass to your "Fire" method? Currently you pass the distance between you and the target. Shouldn't you somehow pass the angle?

ps: Never use "pow" for simple powers. This `(Mathf.Pow(v_, 2))`

should be simply

`(v_ * v_)`

Is there a disadvantage for using `$$anonymous$$athf.Pow(v_, 2)`

ins$$anonymous$$d of `(v_ * v_)`

for a simple power?

Yes, about a factor of "10". First of all $$anonymous$$athf.Pow is (like almost all methods of $$anonymous$$athf) just a wrapper for System.$$anonymous$$ath.Pow just casted to float. All System.$$anonymous$$ath methods work with double. It's literally defined as:

```
public static float Pow(float f, float p)
{
return (float)$$anonymous$$ath.Pow((double)f, (double)p);
}
```

Though the slight casting overhad is not the worst. A simple native floating point multiplication will be carried out directly inline by FPU opcodes while Pow is an actual method call. The main problem is that Pow does work with non-integer powers as well. That means the method has to decompose the power into an integer part and a fractional part.

I ran a quick test and did 1$$anonymous$$ Pow with "2" as power in a loop and it took 733k ticks on my machine. By doing a simple "manual square" (i.e. "x * x") it took only 66k ticks. It roughly translated to about 70 ms vs 6 ms.

ps: decompose means if you have a power of "3.2" it would have to split that power into "3" and "0.2". It can then do a simple integer power with the 3 and in addition calculate the 5th root of the base ((1 / 0.2) --> 5th root). As you might know multiplying two numbers with the same base but different exponent is the same as when you just add the two exponents together. So `(B^x * B^y)`

is the same as `B^(x+y)`

.

### 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.

### Follow this Question

### Related Questions

Find angle between two gameobjects? 1 Answer

Angle calculation not working?? 2 Answers

Angle between two lines in 2D 3 Answers

Problem with calculating damage, value returning 0 1 Answer

Find Vector3 from a starting Vector3, angle, and distance. 1 Answer