public static LinearIntersection RaySphere(ref Vector3d rayOrigin, ref Vector3d rayDirection, ref Vector3d sphereCenter, double sphereRadius)
        {
            LinearIntersection result = new LinearIntersection();

            LineSphere(ref rayOrigin, ref rayDirection, ref sphereCenter, sphereRadius, ref result);
            return(result);
        }
        public static LinearIntersection LineSphere(ref Vector3d lineOrigin, ref Vector3d lineDirection, ref Vector3d sphereCenter, double sphereRadius)
        {
            var result = new LinearIntersection();

            LineSphere(ref lineOrigin, ref lineDirection, ref sphereCenter, sphereRadius, ref result);
            return(result);
        }
        /// <summary>
        /// Intersect ray with sphere and return intersection info (# hits, ray parameters)
        /// </summary>
        public static bool RaySphere(ref Vector3d rayOrigin, ref Vector3d rayDirection, ref Vector3d sphereCenter, double sphereRadius, ref LinearIntersection result)
        {
            // [RMS] adapted from GeometricTools GTEngine
            // https://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Sphere3.h

            LineSphere(ref rayOrigin, ref rayDirection, ref sphereCenter, sphereRadius, ref result);
            if (result.intersects)
            {
                // The line containing the ray intersects the sphere; the t-interval
                // is [t0,t1].  The ray intersects the sphere as long as [t0,t1]
                // overlaps the ray t-interval [0,+infinity).
                if (result.parameter.b < 0)
                {
                    result.intersects       = false;
                    result.numIntersections = 0;
                }
                else if (result.parameter.a < 0)
                {
                    result.numIntersections--;
                    result.parameter.a = result.parameter.b;
                }
            }
            return(result.intersects);
        }
        /// <summary>
        /// Intersect ray with sphere and return intersection info (# hits, ray parameters)
        /// </summary>
        public static bool LineSphere(ref Vector3d lineOrigin, ref Vector3d lineDirection, ref Vector3d sphereCenter, double sphereRadius, ref LinearIntersection result)
        {
            // [RMS] adapted from GeometricTools GTEngine
            // https://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrLine3Sphere3.h

            // The sphere is (X-C)^T*(X-C)-1 = 0 and the line is X = P+t*D.
            // Substitute the line equation into the sphere equation to obtain a
            // quadratic equation Q(t) = t^2 + 2*a1*t + a0 = 0, where a1 = D^T*(P-C),
            // and a0 = (P-C)^T*(P-C)-1.
            Vector3d diff = lineOrigin - sphereCenter;
            double   a0   = diff.LengthSquared - sphereRadius * sphereRadius;
            double   a1   = lineDirection.Dot(diff);

            // Intersection occurs when Q(t) has real roots.
            double discr = a1 * a1 - a0;

            if (discr > 0)
            {
                result.intersects       = true;
                result.numIntersections = 2;
                double root = Math.Sqrt(discr);
                result.parameter.a = -a1 - root;
                result.parameter.b = -a1 + root;
            }
            else if (discr < 0)
            {
                result.intersects       = false;
                result.numIntersections = 0;
            }
            else
            {
                result.intersects       = true;
                result.numIntersections = 1;
                result.parameter.a      = -a1;
                result.parameter.b      = -a1;
            }
            return(result.intersects);
        }