I'm determining a trajectory necessary to hit target B with a projectile launched from point A with a given velocity. No problems there. Obviously, not all points B can be hit with a fixed velocity, so I'm trying to find the maximum distance along AB that can still be hit by the projectile. How might I find this?
1 Answer
Using the code in this answer:
Vector3 toTarget = target.position - transform.position;
// Set up the terms we need to solve the quadratic equations.
float gSquared = Physics.gravity.sqrMagnitude;
float b = speed * speed + Vector3.Dot(toTarget, Physics.gravity);
float discriminant = b * b - gSquared * toTarget.sqrMagnitude;
// Check whether the target is reachable at max speed or less.
if(discriminant < 0) {
// Target is too far away to hit at this speed.
// Abort, or fire at max speed in its general direction?
}
We can see that the limiting threshold between reachable and unreachable targets occurs when discriminant == 0
Let's rewrite this in math form, using \$x \vec d\$ to represent the displacement from our launch position to our farthest reachable point, with \$0 \le x < 1\$. Here \$\vec d\ = \vec B - \vec A\$, represents the total displacement from our launch point \$\vec A\$ to the target point \$\vec B\$, if \$\vec B\$ itself is not reachable.
$$\begin{align} b = v^2 + x\vec d \cdot \vec g\\ b^2 - \|x \vec d\|^2 \|\vec g\|^2 &= 0\\ (v^2 + x^2\vec d \cdot \vec g)^2 - x^2 \|\vec d\|^2 \|\vec g\|^2 &= 0\\ v^4 + 2 x v^2\vec d \cdot \vec g + x^2(\vec d \cdot \vec g)^2 - x^2\|\vec d\|^2\|\vec g\|^2 &= 0\\ x^2\left((\vec d \cdot \vec g)^2 - \|\vec d\|^2\|\vec g\|^2\right) + x (2v^2 \vec d \cdot \vec g) + v^4 &= 0 \end{align}$$
That last line is a basic quadratic which you can solve with the quadratic formula, since all the coefficients are known in terms of your inputs: the target displacement \$\vec d\$, the acceleration due to gravity \$\vec g\$, and the maximum launch speed \$v\$.
This will give you two answers: the positive one is the farthest fraction of the way toward your target \$\vec B\$ that you can hit (or overshoot, if the value is greater than 1, meaning you can hit the target itself no problem). The negative one is how far you can shoot diametrically opposite your target (not super interesting in this case).
In the event that the displacement is parallel to the direction of gravity, then the first term disappears and it's a linear equation with a single solution instead - even easier!