- Home /
How to calculate the angle of a trajectory to hit the target
Hi everyone,
How do I calculate the angle of a trajectory to hit the target, without knowing the velocity. I only know the max height, offset height and the distance to the target.
This is what I got so far (I don't know how to calculate offset height ):
float GetAngle(Vector3 startLocation, Vector3 endLocation, float maxHeight)
{
float distance = Mathf.Sqrt(Mathf.Pow(startLocation.x - endLocation.x,2) + Mathf.Pow(startLocation.z - endLocation.z,2));
float offsetHeight = endLocation.y - startLocation.y;
//how do I calculate offset height in this equation ?
return -Mathf.Atan (4 * maxHeight/ distance ) + Mathf.PI;
}
I use this to calculate the velocity (works fine I only need the correct angle):
float LaunchVelocity (Vector3 startLocation, Vector3 endLocation, float angle)
{
float range = Mathf.Sqrt(Mathf.Pow(startLocation.x - endLocation.x,2) + Mathf.Pow(startLocation.z - endLocation.z,2));
float offsetHeight = endLocation.y - startLocation.y;
float gravity = Physics.gravity.y;
float velocity = range * range * gravity;
velocity /= range * Mathf.Sin(2 * angle) + 2 * offsetHeight * Mathf.Pow(Mathf.Cos(angle),2);
return Mathf.Sqrt(velocity);
}
Is it mandatory that the projectile reaches the maximum height?
To establish the Offset height, you could use Pythagoras... The hypotenuse can be deter$$anonymous$$ed by Vector3.Distance(start, target); which leaves one side remaining.
For theta, there's a similar post here, but its for 2D:
Sorry Agorichyrich but I do not fully understand what you what you mean. Can you finish my GetAngle function?
Use quanternions or something like that. I can't remember much about it, but it worked for me in many cases.
Quaternions just represent angles. They are not intuitive and I imagine that calculating trajectories would be easier in Euler.
Answer by koray1396 · Nov 27, 2014 at 05:09 PM
first, you should need to complete your code, otherwise you will always face similar problems.
I think there is no need to deal with complex formulas, I find simple steps helpful;
VerticalSpeed = Mathf.Sqrt(2*gravity*MaxHeight)
TravelTime = Sqrt(2*(MaxHeight - OffsetHeight) / g) + Sqrt(2*MaxHeight / g)
HorizontalSpeed = Distance / TravelTime
So your speed vector would be VerticalSpeed + HorizontalSpeed.
You can calculate the angle by Mathf.Atan2. Speed would be Magnitude of FinalVector.
This is the correct answer. But, if the projectile doesn't have to reach the $$anonymous$$axHeight, there will be infinite angles to hit the target.
void TrialShootBy$$anonymous$$axHeight(Rigidbody rigid)
{
Vector3 originOfLaunch = Vector3.zero;
Vector3 targetPositionForLanding = Vector3.forward * 10;
//$$anonymous$$ade these points up. Hope you change them!
float maxPermittedHeight = 10f;
//Not only does the code below find a trajectory...
//The curve never goes higher than a provided height.
//See the original question:
//http://answers.unity3d.com/questions/841870/how-to-calculate-the-angle-of-a-trajectory-to-hit.html
float heightDifference =
originOfLaunch.y - targetPositionForLanding.y;
float verticalSpeed =
$$anonymous$$athf.Sqrt
(2 * -Physics.gravity.y * maxPermittedHeight);
float trialAndErrorFudgeICouldNotRemove = 0.06f;
float expectedTravelTime = 0f;
if ($$anonymous$$athf.Sign(heightDifference) == -1)
{
expectedTravelTime =
$$anonymous$$athf.Sqrt
(2 * (maxPermittedHeight - heightDifference) /
-Physics.gravity.y)
+
$$anonymous$$athf.Sqrt
(2 * maxPermittedHeight /
-Physics.gravity.y);
}
else if ($$anonymous$$athf.Sign(heightDifference) == 1)
{
trialAndErrorFudgeICouldNotRemove *= -1;
expectedTravelTime =
$$anonymous$$athf.Sqrt
(2 * (maxPermittedHeight + heightDifference) /
-Physics.gravity.y)
+
$$anonymous$$athf.Sqrt
(2 * maxPermittedHeight /
-Physics.gravity.y);
}
float horizontalSpeed =
Vector3.Distance
(originOfLaunch, targetPositionForLanding)
/ expectedTravelTime;
Vector3 facingTargetWithNoY =
(targetPositionForLanding - originOfLaunch);
facingTargetWithNoY.y = 0f;
Vector3 normalizedForwardDir = facingTargetWithNoY.normalized;
Vector3 launchVector = new Vector3
(normalizedForwardDir.x * horizontalSpeed,
verticalSpeed,
normalizedForwardDir.z * horizontalSpeed);
//quote from the question page linked at the top.
// If you want, "You can calculate the angle by $$anonymous$$athf.Atan2.Speed would be $$anonymous$$agnitude of FinalVector." ???
//Now to add force. $$anonymous$$ake sure it has none already.
rigid.AddForce(-rigid.velocity, Force$$anonymous$$ode.VelocityChange);
//Launch
rigid.AddForce
(launchVector, Force$$anonymous$$ode.VelocityChange);
//And add some of that fudge!
rigid.AddForce
(launchVector * trialAndErrorFudgeICouldNotRemove, Force$$anonymous$$ode.VelocityChange);
}
Got it working by adding a bit of fudge force, messing with the sign of gravity in the equation, but above all: I had to add an if statement that uses "heightDifference" (the offset) with a different sign if it is positive (meaning the origin is above the landing spot).
Hate to say, I actually have to go play with this link for a few hours now. http://answers.unity3d.com/questions/49195/trajectory-of-a-projectile-formula-does-anyone-kno.html Because I don't need to keep to a certain $$anonymous$$AX HEIGHT. I need to keep to a certain LAUNCH VELOCITY
But yeah, if you just need a trajectory, or need to keep below a certain height... my script interpretation of $$anonymous$$oray's theory works O$$anonymous$$
(You might also consider adding a "$$anonymous$$ range" for this whole function. If target is damn close - why lob when you can shoot right at it??)
With the appropriate algorithm, there's no need for an if statement checking whether there is a height difference.
You might want to check out this answer (http://answers.unity3d.com/questions/1087568/3d-trajectory-prediction.html#comment-1343095) I gave on the subject a while back. Specifically, there are examples included for multiple means of generating an optimal trajectory, including a fixed speed for the initial launch velocity.