• 12
• 12
• 9
• 10
• 13

# Is this sphere-capsule intersection?

This topic is 2710 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

The internet knows not of such a thing, so I took a stab at it, adapting Box-Capsule intersection:
        public static bool Intersects(BoundingSphere boundingSphere, Capsule capsule, out Vector3 point)        {            point = Vector3.Zero;            double halfLength = capsule.Line.Vector.Length() / 2;            Vector3 To = boundingSphere.Center - capsule.Line.MidPoint;            double r1 = boundingSphere.Radius + halfLength * Math.Abs(capsule.Line.Vector.X) + capsule.Radius;            double r2 = boundingSphere.Radius + halfLength * Math.Abs(capsule.Line.Vector.Y) + capsule.Radius;            double r3 = boundingSphere.Radius + halfLength * Math.Abs(capsule.Line.Vector.Z) + capsule.Radius;            if (To.SquaredLength() > (r1 * r1 + r2 * r2 + r3 * r3))                return false;            r1 = boundingSphere.Radius * Math.Abs(capsule.Line.Vector.Z) + boundingSphere.Radius * Math.Abs(capsule.Line.Vector.Y);            r2 = boundingSphere.Radius * Math.Abs(capsule.Line.Vector.Z) + boundingSphere.Radius * Math.Abs(capsule.Line.Vector.X);            r3 = boundingSphere.Radius * Math.Abs(capsule.Line.Vector.Y) + boundingSphere.Radius * Math.Abs(capsule.Line.Vector.X);            double r4 = Math.Sqrt(r1 * r1 + r2 * r2 + r3 * r3);            if (Math.Abs(To.Y * capsule.Line.Vector.Z - To.Z * capsule.Line.Vector.Y) > r4 + capsule.Radius)                return false;            if (Math.Abs(To.X * capsule.Line.Vector.Z - To.Z * capsule.Line.Vector.X) > r4 + capsule.Radius)                return false;            if (Math.Abs(To.X * capsule.Line.Vector.Y - To.Y * capsule.Line.Vector.X) > r4 + capsule.Radius)                return false;            point.X = r1; point.Y = r2; point.Z = r3;            return true;        }

##### Share on other sites
Then it occurred to me that this can be reduced down to the distance between lines and then a radius check:
        public static bool Intersects(BoundingSphere boundingSphere, Capsule capsule, out Vector3 point)        {            double line1Distance, line2Distance;            double distance = Line.distance(                new Line(boundingSphere.Center, boundingSphere.Center),                 capsule.Line,                 out point,                out line1Distance,                 out line2Distance                );            Vector3 capsulePoint = capsule.Line.Point1 + (capsule.Line.Vector * line2Distance);            return distance < boundingSphere.Radius + ((point - capsulePoint).Length() + capsule.Radius);        }

I've never written my own swept intersection code before (even if I got the Line-Line off the internet). Which is why I'm asking for help. :)

##### Share on other sites
I am assuming the sphere and capsule are stationary. They intersect when the distance between the sphere center and the line-segment axis of the capsule is smaller or equal to the sum of sphere radius and capsule radius. So all you really need is a calculator of distance between a point and a line segment.

##### Share on other sites
Quote:
 Original post by Dave EberlyI am assuming the sphere and capsule are stationary. They intersect when the distance between the sphere center and the line-segment axis of the capsule is smaller or equal to the sum of sphere radius and capsule radius. So all you really need is a calculator of distance between a point and a line segment.

Thanks for the idea. That would be what I have, then, save that I'm using a line where the two ends are at the same location.

##### Share on other sites
Did I get this right check:
        public static double Distance(            Line line1, Vector3 point,            out Vector3 midpoint, out double lineDistance            )        {            Vector3 pointToLine = point - line1.Point1;            Vector3 toNearestOnLine = Vector3.Dot(pointToLine, Vector3.Normalize(line1.Vector)) *                Vector3.Normalize(line1.Vector);            Vector3 distancePoint = pointToLine - toNearestOnLine;            lineDistance = toNearestOnLine.Length();            midpoint = Vector3.Lerp(point, line1.Point1 + toNearestOnLine, .05);            return distancePoint.Length();        }

##### Share on other sites
Hi,

Just something to keep in mind: the intersection set between a sphere and a capsule is almost never a single point. That is really a degenerate case.
(yeah, sphere-sphere intersection set is also quite complex so its usually not
computed but either approximated or another compromise is done).