public static QuadraticResult QuadraticEquation(float a, float b, float c) { QuadraticResult retval = new QuadraticResult(); float b4ac = b * b - 4 * a * c; if (b4ac < 0) { retval.numResults = 0; } else if (b4ac == 0) { //Mathf.Sqrt(0) is 0 so ignore it retval.numResults = 1; retval.r1 = -b / (2 * a); } else { float sq = Mathf.Sqrt(b4ac); retval.numResults = 2; retval.r1 = (-b + sq) / (2 * a); retval.r2 = (-b - sq) / (2 * a); } return(retval); }
/* * Calc time to intersect of linear moving target, given intial positions and known speed */ public static float CalcIntersectTime(Vector3 enemyPos, Vector3 enemyVelocity, Vector3 firingPos, float bulletSpeed) { //using the expanding sphere vs growing line method //http://playtechs.blogspot.kr/2007/04/aiming-at-moving-target.html //make local, sphere is now at origin Vector3 dif = enemyPos - firingPos; //squared speed dif float a = bulletSpeed * bulletSpeed - Vector3.Dot(enemyVelocity, enemyVelocity); //two times dot of our vector and the escape vel float b = -2 * Vector3.Dot(enemyVelocity, dif); float c = -Vector3.Dot(dif, dif); QuadraticResult res = UTIL.QuadraticEquation(a, b, c); switch (res.numResults) { case 1: if (res.r1 > 0) { return(res.r1); } break; case 2: float max = Mathf.Max(res.r1, res.r2); if (max > 0) { return(max); } break; default: break; } return(Mathf.Infinity); }