/// <summary> /// Determines if the ray intersects with the given sphere. /// </summary> /// <param name="sphere">Sphere to check intersection with</param> /// <returns></returns> public bool IntersectsWith(FSphere sphere, out float intersectionDist) { // From http://gamedev.stackexchange.com/questions/96459/fast-ray-sphere-collision-code // This is the ray origin's offset from the center of the sphere. Vector3 offsetFromSphereCenter = Origin - sphere.Center; float radiusSquared = sphere.Radius * sphere.Radius; float offsetDotRadiusSquared = Vector3.Dot(offsetFromSphereCenter, Direction); // If either of these are true, that means the sphere is behind or surrounding the starting point. // Basically, the sphere is behind the ray's origin, or the ray's origin is within the sphere if (offsetDotRadiusSquared < 0 || Vector3.Dot(offsetFromSphereCenter, offsetFromSphereCenter) < radiusSquared) { intersectionDist = float.MaxValue; return(false); } // Flatten the ray offset onto the plan passing through the sphere's center perpendicular to the ray. // This gives the closest approach of the ray to the center of the sphere. Vector3 flattening = offsetFromSphereCenter - offsetDotRadiusSquared * Direction; float flatteningSquared = Vector3.Dot(flattening, flattening); // If this is true, the closest approach of the ray to the sphere is outside the sphere. // Basically, the ray doesn't intersect the sphere. if (flatteningSquared > radiusSquared) { intersectionDist = float.MaxValue; return(false); } // This is the distance from the plane where the ray enters and exits the sphere. float distanceFromPlane = (float)Math.Sqrt(radiusSquared - flatteningSquared); // This is the intersection point relative to the sphere center. Vector3 intersection = flattening - distanceFromPlane * Direction; Vector3 dirToIntersection = sphere.Center + intersection; dirToIntersection.Normalize(); intersectionDist = (Origin - intersection).Length; return(true); }
/// <summary> /// Determines if the ray intersects with the given sphere. /// </summary> /// <param name="sphere">Sphere to check intersection with</param> /// <returns></returns> public bool IntersectsWith(FSphere sphere, out float intersectionDist) { // From http://gamedev.stackexchange.com/questions/96459/fast-ray-sphere-collision-code // This is the ray origin's offset from the center of the sphere. Vector3 offsetFromSphereCenter = Origin - sphere.Center; float radiusSquared = sphere.Radius * sphere.Radius; float offsetDotRadiusSquared = Vector3.Dot(offsetFromSphereCenter, Direction); // If either of these are true, that means the sphere is behind or surrounding the starting point. // Basically, the sphere is behind the ray's origin, or the ray's origin is within the sphere if (offsetDotRadiusSquared < 0 || Vector3.Dot(offsetFromSphereCenter, offsetFromSphereCenter) < radiusSquared) { intersectionDist = float.MaxValue; return false; } // Flatten the ray offset onto the plan passing through the sphere's center perpendicular to the ray. // This gives the closest approach of the ray to the center of the sphere. Vector3 flattening = offsetFromSphereCenter - offsetDotRadiusSquared * Direction; float flatteningSquared = Vector3.Dot(flattening, flattening); // If this is true, the closest approach of the ray to the sphere is outside the sphere. // Basically, the ray doesn't intersect the sphere. if (flatteningSquared > radiusSquared) { intersectionDist = float.MaxValue; return false; } // This is the distance from the plane where the ray enters and exits the sphere. float distanceFromPlane = (float)Math.Sqrt(radiusSquared - flatteningSquared); // This is the intersection point relative to the sphere center. Vector3 intersection = flattening - distanceFromPlane * Direction; Vector3 dirToIntersection = sphere.Center + intersection; dirToIntersection.Normalize(); intersectionDist = (Origin - intersection).Length; return true; }