GteIntrLine3AlignedBox3.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/GteVector3.h>
12 #include <Mathematics/GteLine.h>
13 #include <Mathematics/GteFIQuery.h>
14 #include <Mathematics/GteTIQuery.h>
15 #include <limits>
16 
17 // The queries consider the box to be a solid.
18 //
19 // The test-intersection queries use the method of separating axes. The
20 // find-intersection queries use parametric clipping against the six faces of
21 // the box.
22 
23 namespace gte
24 {
25 
26 template <typename Real>
27 class TIQuery<Real, Line3<Real>, AlignedBox3<Real>>
28 {
29 public:
30  struct Result
31  {
32  bool intersect;
33  };
34 
35  Result operator()(Line3<Real> const& line, AlignedBox3<Real> const& box);
36 
37 protected:
38  void DoQuery(Vector3<Real> const& lineOrigin,
39  Vector3<Real> const& lineDirection, Vector3<Real> const& boxExtent,
40  Result& result);
41 };
42 
43 template <typename Real>
44 class FIQuery<Real, Line3<Real>, AlignedBox3<Real>>
45 {
46 public:
47  struct Result
48  {
49  bool intersect;
50  int numPoints;
51  Real lineParameter[2];
52  Vector3<Real> point[2];
53  };
54 
55  Result operator()(Line3<Real> const& line, AlignedBox3<Real> const& box);
56 
57 protected:
58  void DoQuery(Vector3<Real> const& lineOrigin,
59  Vector3<Real> const& lineDirection, Vector3<Real> const& boxExtent,
60  Result& result);
61 
62 private:
63  // Test whether the current clipped segment intersects the current test
64  // plane. If the return value is 'true', the segment does intersect the
65  // plane and is clipped; otherwise, the segment is culled (no intersection
66  // with box).
67  static bool Clip(Real denom, Real numer, Real& t0, Real& t1);
68 };
69 
70 
71 template <typename Real>
74  Line3<Real> const& line, AlignedBox3<Real> const& box)
75 {
76  // Get the centered form of the aligned box. The axes are implicitly
77  // Axis[d] = Vector3<Real>::Unit(d).
78  Vector3<Real> boxCenter, boxExtent;
79  box.GetCenteredForm(boxCenter, boxExtent);
80 
81  // Transform the line to the aligned-box coordinate system.
82  Vector3<Real> lineOrigin = line.origin - boxCenter;
83 
84  Result result;
85  DoQuery(lineOrigin, line.direction, boxExtent, result);
86  return result;
87 }
88 
89 template <typename Real>
91  Vector3<Real> const& lineOrigin, Vector3<Real> const& lineDirection,
92  Vector3<Real> const& boxExtent, Result& result)
93 {
94  Vector3<Real> WxD = Cross(lineDirection, lineOrigin);
95  Real absWdU[3] =
96  {
97  std::abs(lineDirection[0]),
98  std::abs(lineDirection[1]),
99  std::abs(lineDirection[2])
100  };
101 
102  if (std::abs(WxD[0]) > boxExtent[1] * absWdU[2] + boxExtent[2] * absWdU[1])
103  {
104  result.intersect = false;
105  return;
106  }
107 
108  if (std::abs(WxD[1]) > boxExtent[0] * absWdU[2] + boxExtent[2] * absWdU[0])
109  {
110  result.intersect = false;
111  return;
112  }
113 
114  if (std::abs(WxD[2]) > boxExtent[0] * absWdU[1] + boxExtent[1] * absWdU[0])
115  {
116  result.intersect = false;
117  return;
118  }
119 
120  result.intersect = true;
121 }
122 
123 template <typename Real>
126  Line3<Real> const& line, AlignedBox3<Real> const& box)
127 {
128  // Get the centered form of the aligned box. The axes are implicitly
129  // Axis[d] = Vector3<Real>::Unit(d).
130  Vector3<Real> boxCenter, boxExtent;
131  box.GetCenteredForm(boxCenter, boxExtent);
132 
133  // Transform the line to the aligned-box coordinate system.
134  Vector3<Real> lineOrigin = line.origin - boxCenter;
135 
136  Result result;
137  DoQuery(lineOrigin, line.direction, boxExtent, result);
138  for (int i = 0; i < result.numPoints; ++i)
139  {
140  result.point[i] =
141  line.origin + result.lineParameter[i] * line.direction;
142  }
143  return result;
144 }
145 
146 template <typename Real>
148  Vector3<Real> const& lineOrigin, Vector3<Real> const& lineDirection,
149  Vector3<Real> const& boxExtent, Result& result)
150 {
151  // The line t-values are in the interval (-infinity,+infinity). Clip the
152  // line against all six planes of an aligned box in centered form. The
153  // result.numEndpoints is
154  // 0, no intersection
155  // 1, intersect in a single point (t0 is line parameter of point)
156  // 2, intersect in a segment (line parameter interval is [t0,t1])
157  Real t0 = -std::numeric_limits<Real>::max();
158  Real t1 = std::numeric_limits<Real>::max();
159  if (Clip(+lineDirection[0], -lineOrigin[0] - boxExtent[0], t0, t1) &&
160  Clip(-lineDirection[0], +lineOrigin[0] - boxExtent[0], t0, t1) &&
161  Clip(+lineDirection[1], -lineOrigin[1] - boxExtent[1], t0, t1) &&
162  Clip(-lineDirection[1], +lineOrigin[1] - boxExtent[1], t0, t1) &&
163  Clip(+lineDirection[2], -lineOrigin[2] - boxExtent[2], t0, t1) &&
164  Clip(-lineDirection[2], +lineOrigin[2] - boxExtent[2], t0, t1))
165  {
166  result.intersect = true;
167  if (t1 > t0)
168  {
169  result.numPoints = 2;
170  result.lineParameter[0] = t0;
171  result.lineParameter[1] = t1;
172  }
173  else
174  {
175  result.numPoints = 1;
176  result.lineParameter[0] = t0;
177  result.lineParameter[1] = t0; // Used by derived classes.
178  }
179  return;
180  }
181 
182  result.intersect = false;
183  result.numPoints = 0;
184 }
185 
186 template <typename Real>
187 bool FIQuery<Real, Line3<Real>, AlignedBox3<Real>>::Clip(Real denom,
188  Real numer, Real& t0, Real& t1)
189 {
190  if (denom > (Real)0)
191  {
192  if (numer > denom*t1)
193  {
194  return false;
195  }
196  if (numer > denom*t0)
197  {
198  t0 = numer / denom;
199  }
200  return true;
201  }
202  else if (denom < (Real)0)
203  {
204  if (numer > denom*t0)
205  {
206  return false;
207  }
208  if (numer > denom*t1)
209  {
210  t1 = numer / denom;
211  }
212  return true;
213  }
214  else
215  {
216  return numer <= (Real)0;
217  }
218 }
219 
220 
221 }
gte::BSNumber< UIntegerType > abs(gte::BSNumber< UIntegerType > const &number)
Definition: GteBSNumber.h:966
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t0
Definition: glext.h:9013
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
Definition: glext.h:9013
DualQuaternion< Real > Cross(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