Collision Detection 4 – Ray Sphere

Ray – Sphere

Here’s quite a neat trick to calculate if a ray if you have the Ray-Plane collision down. I’m not sure how fast it is compared to other algorithms, but to me it was a logical step from Ray-Plane that I worked out on paper.
First rule of thumb, make the problem 2 Dimensional: As the Sphere is the same shape from all sides, it can easily transform into a 2D circle. Next pretend we are looking at the 2D image of the Sphere from the view of the RayDirection, so the Ray casts downwards into the circle from above.
We can imagine a plane at the centre of the circle with its normal pointing towards the inverse of the ray direction so the plane faces us (The RayDirection). Hopefully now you can see how to solve this once we have the collision point on the plane.

To get the collision point we just do a simple Ray-Plane test with:
RayOrigin being the rays origin,
RayDirection being the rays direction
PlaneOrigin being the spheres origin
PlaneNormal being (-1)*RayDirection (So it’s pointing towards the ray direction)

You may notice that the Ray direction and Plane normal will always point towards each other so they can never be parallel, and the ray will always hit the plane.

What will be returned from the Ray-Plane test is a collision point. This can be subtracted from SphereOrigin to find the distance between the ray collision point and Sphere Origin (Using Pythagoras):

CollisonDistance = Sqrt((SphereOrX – RayColX)² + (SphereOrY – RayColY)² + (SphereOrZ – RayColZ)²)

If Collision distance is greater than the spheres radius, then the ray does not intersect the sphere, if it’s less than the radius of the sphere, it intersects.

Getting the location of the collision

To retrieve the point of collision on the surface of the sphere (which is 3D and constantly changes) We simply find how far the collision point is from the edge of the sphere:

Difference = Radius – Collision Distance

And subtract this from our lambda time calculated from the ray-Plane calculation:

CollisonPosition = RayOrigin + ((time – difference)*rayDir)

Voilà! We have the precise position of an intersection on the surface of a 3D sphere using only a 2D circle and the D=ST equation.