Metric CalcInterceptTime (const CVector &vTarget, const CVector &vTargetVel, Metric rMissileSpeed, Metric *retrRange) // CalcInterceptTime // // Returns the time that it would take to intercept a target // at vTarget, moving with velocity vTargetVel, with // a missile of speed rMissileSpeed. Returns < 0.0 if the missile cannot // intercept the target. // // The formula for interception is: // // A +- B sqrt(C) // t = -------------- // D // // Where A = B rVi // B = 2 rRange // C = rMissileSpeed^2 - rVj^2 // D = 2 (C - rVi^2) { Metric rRange = vTarget.Length(); CVector vPosNormal = vTarget / rRange; if (retrRange) *retrRange = rRange; // Compute the orthogonals of the velocity along the position vector Metric rVi, rVj; vTargetVel.GenerateOrthogonals(vPosNormal, &rVi, &rVj); // Figure out the inside of the square root. If this value is negative // then we don't have an interception course. Metric C = rMissileSpeed * rMissileSpeed - rVj * rVj; if (C < 0.0) return -1.0; // Figure out the denominator. If this value is 0 then we don't // have an interception course. Metric D = 2 * (C - rVi * rVi); if (D == 0.0) return -1.0; // Compute A and B Metric B = 2 * rRange; Metric A = B * rVi; // Compute both roots Metric Z = B * sqrt(C); Metric R1 = (A + Z) / D; Metric R2 = (A - Z) / D; // If the first root is positive then return it if (R1 > 0.0) return R1; // Otherwise we return the second root, which may or may not // be positive return R2; }