GteIntrRay3Sphere3.h
Go to the documentation of this file.
1 // David Eberly, Geometric Tools, Redmond WA 98052
2 // Copyright (c) 1998-2017
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
6 // File Version: 3.0.0 (2016/06/19)
7 
8 #pragma once
9 
10 #include <Mathematics/GteRay.h>
13 
14 namespace gte
15 {
16 
17 template <typename Real>
18 class TIQuery<Real, Ray3<Real>, Sphere3<Real>>
19 {
20 public:
21  struct Result
22  {
23  bool intersect;
24  };
25 
26  Result operator()(Ray3<Real> const& ray, Sphere3<Real> const& sphere);
27 };
28 
29 template <typename Real>
30 class FIQuery<Real, Ray3<Real>, Sphere3<Real>>
31  :
32  public FIQuery<Real, Line3<Real>, Sphere3<Real>>
33 {
34 public:
35  struct Result
36  :
37  public FIQuery<Real, Line3<Real>, Sphere3<Real>>::Result
38  {
39  // No additional information to compute.
40  };
41 
42  Result operator()(Ray3<Real> const& ray, Sphere3<Real> const& sphere);
43 
44 protected:
45  void DoQuery(Vector3<Real> const& rayOrigin,
46  Vector3<Real> const& rayDirection, Sphere3<Real> const& sphere,
47  Result& result);
48 };
49 
50 
51 template <typename Real>
52 typename TIQuery<Real, Ray3<Real>, Sphere3<Real>>::Result
54  Ray3<Real> const& ray, Sphere3<Real> const& sphere)
55 {
56  // The sphere is (X-C)^T*(X-C)-1 = 0 and the line is X = P+t*D.
57  // Substitute the line equation into the sphere equation to obtain a
58  // quadratic equation Q(t) = t^2 + 2*a1*t + a0 = 0, where a1 = D^T*(P-C),
59  // and a0 = (P-C)^T*(P-C)-1.
60  Result result;
61 
62  Vector3<Real> diff = ray.origin - sphere.center;
63  Real a0 = Dot(diff, diff) - sphere.radius * sphere.radius;
64  if (a0 <= (Real)0)
65  {
66  // P is inside the sphere.
67  result.intersect = true;
68  return result;
69  }
70  // else: P is outside the sphere
71 
72  Real a1 = Dot(ray.direction, diff);
73  if (a1 >= (Real)0)
74  {
75  result.intersect = false;
76  return result;
77  }
78 
79  // Intersection occurs when Q(t) has real roots.
80  Real discr = a1*a1 - a0;
81  result.intersect = (discr >= (Real)0);
82  return result;
83 }
84 
85 template <typename Real>
86 typename FIQuery<Real, Ray3<Real>, Sphere3<Real>>::Result
88  Ray3<Real> const& ray, Sphere3<Real> const& sphere)
89 {
90  Result result;
91  DoQuery(ray.origin, ray.direction, sphere, result);
92  for (int i = 0; i < result.numIntersections; ++i)
93  {
94  result.point[i] = ray.origin + result.parameter[i] * ray.direction;
95  }
96  return result;
97 }
98 
99 template <typename Real>
101  Vector3<Real> const& rayOrigin, Vector3<Real> const& rayDirection,
102  Sphere3<Real> const& sphere, Result& result)
103 {
104  FIQuery<Real, Line3<Real>, Sphere3<Real>>::DoQuery(rayOrigin,
105  rayDirection, sphere, result);
106 
107  if (result.intersect)
108  {
109  // The line containing the ray intersects the sphere; the t-interval
110  // is [t0,t1]. The ray intersects the sphere as long as [t0,t1]
111  // overlaps the ray t-interval [0,+infinity).
112  std::array<Real, 2> rayInterval =
113  { (Real)0, std::numeric_limits<Real>::max() };
114  FIQuery<Real, std::array<Real, 2>, std::array<Real, 2>> iiQuery;
115  auto iiResult = iiQuery(result.parameter, rayInterval);
116  if (iiResult.intersect)
117  {
118  result.numIntersections = iiResult.numIntersections;
119  result.parameter = iiResult.overlap;
120  }
121  else
122  {
123  result.intersect = false;
124  result.numIntersections = 0;
125  }
126  }
127 }
128 
129 
130 }
DualQuaternion< Real > Dot(DualQuaternion< Real > const &d0, DualQuaternion< Real > const &d1)
Result operator()(Type0 const &primitive0, Type1 const &primitive1)
GLuint64EXT * result
Definition: glext.h:10003


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 04:00:00