GteIntrLine2AlignedBox2.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/GteVector2.h>
11 #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 four edges of
21 // the box.
22 
23 namespace gte
24 {
25 
26 template <typename Real>
27 class TIQuery<Real, Line2<Real>, AlignedBox2<Real>>
28 {
29 public:
30  struct Result
31  {
32  bool intersect;
33  };
34 
35  Result operator()(Line2<Real> const& line, AlignedBox2<Real> const& box);
36 
37 protected:
38  void DoQuery(Vector2<Real> const& lineOrigin,
39  Vector2<Real> const& lineDirection, Vector2<Real> const& boxExtent,
40  Result& result);
41 };
42 
43 template <typename Real>
44 class FIQuery<Real, Line2<Real>, AlignedBox2<Real>>
45 {
46 public:
47  struct Result
48  {
49  bool intersect;
51  std::array<Real, 2> parameter;
52  std::array<Vector2<Real>, 2> point;
53  };
54 
55  Result operator()(Line2<Real> const& line, AlignedBox2<Real> const& box);
56 
57 protected:
58  void DoQuery(Vector2<Real> const& lineOrigin,
59  Vector2<Real> const& lineDirection, Vector2<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  Line2<Real> const& line, AlignedBox2<Real> const& box)
75 {
76  // Get the centered form of the aligned box. The axes are implicitly
77  // Axis[d] = Vector2<Real>::Unit(d).
78  Vector2<Real> boxCenter, boxExtent;
79  box.GetCenteredForm(boxCenter, boxExtent);
80 
81  // Transform the line to the aligned-box coordinate system.
82  Vector2<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  Vector2<Real> const& lineOrigin, Vector2<Real> const& lineDirection,
92  Vector2<Real> const& boxExtent, Result& result)
93 {
94  Real LHS = std::abs(DotPerp(lineDirection, lineOrigin));
95  Real RHS =
96  boxExtent[0] * std::abs(lineDirection[1]) +
97  boxExtent[1] * std::abs(lineDirection[0]);
98  result.intersect = (LHS <= RHS);
99 }
100 
101 template <typename Real>
104  Line2<Real> const& line, AlignedBox2<Real> const& box)
105 {
106  // Get the centered form of the aligned box. The axes are implicitly
107  // Axis[d] = Vector2<Real>::Unit(d).
108  Vector2<Real> boxCenter, boxExtent;
109  box.GetCenteredForm(boxCenter, boxExtent);
110 
111  // Transform the line to the aligned-box coordinate system.
112  Vector2<Real> lineOrigin = line.origin - boxCenter;
113 
114  Result result;
115  DoQuery(lineOrigin, line.direction, boxExtent, result);
116  for (int i = 0; i < result.numIntersections; ++i)
117  {
118  result.point[i] = line.origin + result.parameter[i] * line.direction;
119  }
120  return result;
121 }
122 
123 template <typename Real>
125  Vector2<Real> const& lineOrigin, Vector2<Real> const& lineDirection,
126  Vector2<Real> const& boxExtent, Result& result)
127 {
128  // The line t-values are in the interval (-infinity,+infinity). Clip the
129  // line against all four planes of an aligned box in centered form. The
130  // result.numPoints is
131  // 0, no intersection
132  // 1, intersect in a single point (t0 is line parameter of point)
133  // 2, intersect in a segment (line parameter interval is [t0,t1])
134  Real t0 = -std::numeric_limits<Real>::max();
135  Real t1 = std::numeric_limits<Real>::max();
136  if (Clip(+lineDirection[0], -lineOrigin[0] - boxExtent[0], t0, t1) &&
137  Clip(-lineDirection[0], +lineOrigin[0] - boxExtent[0], t0, t1) &&
138  Clip(+lineDirection[1], -lineOrigin[1] - boxExtent[1], t0, t1) &&
139  Clip(-lineDirection[1], +lineOrigin[1] - boxExtent[1], t0, t1))
140  {
141  result.intersect = true;
142  if (t1 > t0)
143  {
144  result.numIntersections = 2;
145  result.parameter[0] = t0;
146  result.parameter[1] = t1;
147  }
148  else
149  {
150  result.numIntersections = 1;
151  result.parameter[0] = t0;
152  result.parameter[1] = t0; // Used by derived classes.
153  }
154  return;
155  }
156 
157  result.intersect = false;
158  result.numIntersections = 0;
159 }
160 
161 template <typename Real>
162 bool FIQuery<Real, Line2<Real>, AlignedBox2<Real>>::Clip(Real denom,
163  Real numer, Real& t0, Real& t1)
164 {
165  if (denom > (Real)0)
166  {
167  if (numer > denom*t1)
168  {
169  return false;
170  }
171  if (numer > denom*t0)
172  {
173  t0 = numer / denom;
174  }
175  return true;
176  }
177  else if (denom < (Real)0)
178  {
179  if (numer > denom*t0)
180  {
181  return false;
182  }
183  if (numer > denom*t1)
184  {
185  t1 = numer / denom;
186  }
187  return true;
188  }
189  else
190  {
191  return numer <= (Real)0;
192  }
193 }
194 
195 
196 }
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
Real DotPerp(Vector2< Real > const &v0, Vector2< Real > const &v1)
Definition: GteVector2.h:117
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