GteIntrRay3Ellipsoid3.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 
11 #include <Mathematics/GteRay.h>
14 
15 // The queries consider the ellipsoid to be a solid.
16 
17 namespace gte
18 {
19 
20 template <typename Real>
21 class TIQuery<Real, Ray3<Real>, Ellipsoid3<Real>>
22 {
23 public:
24  struct Result
25  {
26  bool intersect;
27  };
28 
29  Result operator()(Ray3<Real> const& ray,
30  Ellipsoid3<Real> const& ellipsoid);
31 };
32 
33 template <typename Real>
34 class FIQuery<Real, Ray3<Real>, Ellipsoid3<Real>>
35  :
36  public FIQuery<Real, Line3<Real>, Ellipsoid3<Real>>
37 {
38 public:
39  struct Result
40  :
41  public FIQuery<Real, Line3<Real>, Ellipsoid3<Real>>::Result
42  {
43  // No additional information to compute.
44  };
45 
46  Result operator()(Ray3<Real> const& ray,
47  Ellipsoid3<Real> const& ellipsoid);
48 
49 protected:
50  void DoQuery(Vector3<Real> const& rayOrigin,
51  Vector3<Real> const& rayDirection, Ellipsoid3<Real> const& ellipsoid,
52  Result& result);
53 };
54 
55 
56 template <typename Real>
59  Ray3<Real> const& ray, Ellipsoid3<Real> const& ellipsoid)
60 {
61  // The ellipsoid is (X-K)^T*M*(X-K)-1 = 0 and the line is X = P+t*D.
62  // Substitute the line equation into the ellipsoid equation to obtain
63  // a quadratic equation Q(t) = a2*t^2 + 2*a1*t + a0 = 0, where
64  // a2 = D^T*M*D, a1 = D^T*M*(P-K), and a0 = (P-K)^T*M*(P-K)-1.
65  Result result;
66 
68  ellipsoid.GetM(M);
69 
70  Vector3<Real> diff = ray.origin - ellipsoid.center;
71  Vector3<Real> matDir = M*ray.direction;
72  Vector3<Real> matDiff = M*diff;
73  Real a2 = Dot(ray.direction, matDir);
74  Real a1 = Dot(ray.direction, matDiff);
75  Real a0 = Dot(diff, matDiff) - (Real)1;
76 
77  Real discr = a1*a1 - a0*a2;
78  if (discr >= (Real)0)
79  {
80  // Test whether ray origin is inside ellipsoid.
81  if (a0 <= (Real)0)
82  {
83  result.intersect = true;
84  }
85  else
86  {
87  // At this point, Q(0) = a0 > 0 and Q(t) has real roots. It is
88  // also the case that a2 > 0, since M is positive definite,
89  // implying that D^T*M*D > 0 for any nonzero vector D. Thus,
90  // an intersection occurs only when Q'(0) < 0.
91  result.intersect = (a1 < (Real)0);
92  }
93  }
94  else
95  {
96  // No intersection if Q(t) has no real roots.
97  result.intersect = false;
98  }
99 
100  return result;
101 }
102 
103 template <typename Real>
106  Ray3<Real> const& ray, Ellipsoid3<Real> const& ellipsoid)
107 {
108  Result result;
109  DoQuery(ray.origin, ray.direction, ellipsoid, result);
110  for (int i = 0; i < result.numIntersections; ++i)
111  {
112  result.point[i] = ray.origin + result.parameter[i] * ray.direction;
113  }
114  return result;
115 }
116 
117 template <typename Real>
119  Vector3<Real> const& rayOrigin, Vector3<Real> const& rayDirection,
120  Ellipsoid3<Real> const& ellipsoid, Result& result)
121 {
122  FIQuery<Real, Line3<Real>, Ellipsoid3<Real>>::DoQuery(rayOrigin,
123  rayDirection, ellipsoid, result);
124 
125  if (result.intersect)
126  {
127  // The line containing the ray intersects the ellipsoid; the
128  // t-interval is [t0,t1]. The ray intersects the capsule as long as
129  // [t0,t1] overlaps the ray t-interval [0,+infinity).
130  std::array<Real, 2> rayInterval =
131  { (Real)0, std::numeric_limits<Real>::max() };
132  FIQuery<Real, std::array<Real, 2>, std::array<Real, 2>> iiQuery;
133  auto iiResult = iiQuery(result.parameter, rayInterval);
134  if (iiResult.intersect)
135  {
136  result.numIntersections = iiResult.numIntersections;
137  result.parameter = iiResult.overlap;
138  }
139  else
140  {
141  result.intersect = false;
142  result.numIntersections = 0;
143  }
144  }
145 }
146 
147 
148 }
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