Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* Test the intersection of a ray and a sphere in three dimensional space.
- * Returns 0, 1 or 2 intersection points. The first intersection point, if
- * any, is written into #result and the sphere's surface normal into
- * #normal.
- *
- * @param s - The origin of the ray.
- * @param d - The direction of the line (a unit vector)
- * @param c - The center of the sphere
- * @param r - The radius of the sphere
- * @param p1 - The first hitpoint on the sphere.
- * @param p2 - The second hitpoint on the sphere.
- * @return The number of intersections (0, 1 or 2).
- *
- * Thanks go out to http://gamedev.stackexchange.com/a/96469/9616
- */
- template <typename T>
- inline int test_ray_sphere_intersection(
- vector<3, T> const& s, vector<3, T> const& d, vector<3, T> const& c,
- T r, vector<3, T>* p2, vector<3, T>* p1)
- {
- // Calculate ray start's offset from the sphere center
- vector<3, T> p = s - c;
- T rSquared = r * r;
- T p_d = p.dot(d);
- // The sphere is behind or surrounding the start point.
- if (p_d > 0 || p.dot(p) < rSquared)
- return 0;
- // Flatten p into the plane passing through c perpendicular to the ray.
- // This gives the closest approach of the ray to the center.
- vector<3, T> a = p - p_d * d;
- T aSquared = a.dot(a);
- // Closest approach is outside the sphere.
- if (aSquared > rSquared)
- return 0;
- // Calculate distance from plane where ray enters/exits the sphere.
- T h = std::sqrt(rSquared - aSquared);
- // Calculate intersection point relative to sphere center, then
- // derive the first and second hit point.
- if (p1) *p1 = c + (a + h * d);
- if (aSquared == rSquared)
- return 1;
- if (p2) *p2 = c + (a - h * d);
- return 2;
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement