/// <summary> /// Computes an intersection of the ray and the circle /// </summary> public static bool RayCircle(Vector2 rayOrigin, Vector2 rayDirection, Vector2 circleCenter, float circleRadius, out IntersectionRayCircle intersection) { Vector2 originToCenter = circleCenter - rayOrigin; float centerProjection = Vector2.Dot(rayDirection, originToCenter); if (centerProjection + circleRadius < -Geometry.Epsilon) { intersection = IntersectionRayCircle.None(); return(false); } float sqrDistanceToLine = originToCenter.sqrMagnitude - centerProjection * centerProjection; float sqrDistanceToIntersection = circleRadius * circleRadius - sqrDistanceToLine; if (sqrDistanceToIntersection < -Geometry.Epsilon) { intersection = IntersectionRayCircle.None(); return(false); } if (sqrDistanceToIntersection < Geometry.Epsilon) { if (centerProjection < -Geometry.Epsilon) { intersection = IntersectionRayCircle.None(); return(false); } intersection = IntersectionRayCircle.Point(rayOrigin + rayDirection * centerProjection); return(true); } // Line intersection float distanceToIntersection = Mathf.Sqrt(sqrDistanceToIntersection); float distanceA = centerProjection - distanceToIntersection; float distanceB = centerProjection + distanceToIntersection; if (distanceA < -Geometry.Epsilon) { if (distanceB < -Geometry.Epsilon) { intersection = IntersectionRayCircle.None(); return(false); } intersection = IntersectionRayCircle.Point(rayOrigin + rayDirection * distanceB); return(true); } Vector2 pointA = rayOrigin + rayDirection * distanceA; Vector2 pointB = rayOrigin + rayDirection * distanceB; intersection = IntersectionRayCircle.TwoPoints(pointA, pointB); return(true); }
/// <summary> /// Computes an intersection of the ray and the circle /// </summary> public static bool RayCircle(Ray2D ray, Circle2 circle, out IntersectionRayCircle intersection) { return(RayCircle(ray.origin, ray.direction, circle.center, circle.radius, out intersection)); }