/// <summary> /// ѕересечет ли точка, движуща¤с¤ равномерно от точки arr0 до точки arr1, нашу цель(сферу радиуцсом Radius), движущуюс¤ равномерно /// от точки trg0 до точки trg1. Ѕудем считать, что в момент времени t0 - точка находитс¤ в arr0, наша цель (сфера) в точке trg0, /// в момент времени t1 - точка - в arr1, цель - в trg1; /// </summary> /// <param name="arr0"></param> /// <param name="arr1"></param> /// <param name="trg0"></param> /// <param name="trg1"></param> /// <param name="radius"></param> /// <returns>-1 - если не пересечет, [0;1] - дол¤ вектора в момент пересечени¤</returns> public static double HitRadius(Vector3D arr0, Vector3D arr1, Vector3D trg0, Vector3D trg1, double radius) { var v0 = arr0 - trg0; if (v0.GetLength() <= radius) { return(0d); } var v1 = arr1 - trg1; var c1 = v0.GetLengthSquared(); var c2 = Vector3D.DotProduct(v0, v1); var c3 = v1.GetLengthSquared(); var r2 = radius * radius; var a = c1 - 2 * c2 + c3; var b = 2 * c2 - 2 * c1; var c = c1 - r2; if (c > 0 && a + b + c > 0) { return(-1d); } if (System.Math.Abs(a) < MathFunctions.EpsilonD) { var ans = -c / b; return(ans >= 0d && ans <= 1d ? ans : -1d); } else { var d = b * b - 4 * a * c; if (d < 0) { return(-1d); } var x1 = (-b + System.Math.Sqrt(d)) / (2 * a); var xx2 = (-b - System.Math.Sqrt(d)) / (2 * a); var x2 = System.Math.Max(x1, xx2); x1 = System.Math.Min(x1, xx2); return (x1 >= 0d && x1 <= 1d ? x1 : x2 >= 0d && x2 <= 1d ? x2 : -1d); } }
/// <summary> /// DOT prod a vector by a vector. /// </summary> /// <param name="v1">A <see cref="Vector3D"/> instance.</param> /// <param name="v2">A scalar.</param> /// <returns>A new <see cref="Vector3D"/> containing the result.</returns> public static double operator *(Vector3D v1, Vector3D v2) { return(Vector3D.DotProduct(v1, v2)); }