GteIntrSegment2AlignedBox2.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/GteSegment.h>
14 
15 // The queries consider the box to be a solid.
16 //
17 // The test-intersection queries use the method of separating axes. The
18 // find-intersection queries use parametric clipping against the four edges of
19 // the box.
20 
21 namespace gte
22 {
23 
24 
25 template <typename Real>
26 class TIQuery<Real, Segment2<Real>, AlignedBox2<Real>>
27  :
28  public TIQuery<Real, Line2<Real>, AlignedBox2<Real>>
29 {
30 public:
31  struct Result
32  :
33  public TIQuery<Real, Line2<Real>, AlignedBox2<Real>>::Result
34  {
35  // No additional information to compute.
36  };
37 
38  Result operator()(Segment2<Real> const& segment,
39  AlignedBox2<Real> const& box);
40 
41 protected:
42  void DoQuery(Vector2<Real> const& segOrigin,
43  Vector2<Real> const& segDirection, Real segExtent,
44  Vector2<Real> const& boxExtent, Result& result);
45 };
46 
47 template <typename Real>
48 class FIQuery<Real, Segment2<Real>, AlignedBox2<Real>>
49  :
50  public FIQuery<Real, Line2<Real>, AlignedBox2<Real>>
51 {
52 public:
53  struct Result
54  :
55  public FIQuery<Real, Line2<Real>, AlignedBox2<Real>>::Result
56  {
57  // The base class parameter[] values are t-values for the
58  // segment parameterization (1-t)*p[0] + t*p[1], where t in [0,1].
59  // The values in this class are s-values for the centered form
60  // C + s * D, where s in [-e,e] and e is the extent of the segment.
61  std::array<Real, 2> cdeParameter;
62  };
63 
64  Result operator()(Segment2<Real> const& segment,
65  AlignedBox2<Real> const& box);
66 
67 protected:
68  void DoQuery(Vector2<Real> const& segOrigin,
69  Vector2<Real> const& segDirection, Real segExtent,
70  Vector2<Real> const& boxExtent, Result& result);
71 };
72 
73 
74 template <typename Real>
77  Segment2<Real> const& segment, AlignedBox2<Real> const& box)
78 {
79  // Get the centered form of the aligned box. The axes are implicitly
80  // Axis[d] = Vector2<Real>::Unit(d).
81  Vector2<Real> boxCenter, boxExtent;
82  box.GetCenteredForm(boxCenter, boxExtent);
83 
84  // Transform the segment to a centered form in the aligned-box coordinate
85  // system.
86  Vector2<Real> transformedP0 = segment.p[0] - boxCenter;
87  Vector2<Real> transformedP1 = segment.p[1] - boxCenter;
88  Segment2<Real> transformedSegment(transformedP0, transformedP1);
89  Vector2<Real> segOrigin, segDirection;
90  Real segExtent;
91  transformedSegment.GetCenteredForm(segOrigin, segDirection, segExtent);
92 
93  Result result;
94  DoQuery(segOrigin, segDirection, segExtent, boxExtent, result);
95  return result;
96 }
97 
98 template <typename Real>
100  Vector2<Real> const& segOrigin, Vector2<Real> const& segDirection,
101  Real segExtent, Vector2<Real> const& boxExtent, Result& result)
102 {
103  for (int i = 0; i < 2; ++i)
104  {
105  Real lhs = fabs(segOrigin[i]);
106  Real rhs = boxExtent[i] + segExtent * fabs(segDirection[i]);
107  if (lhs > rhs)
108  {
109  result.intersect = false;
110  return;
111  }
112  }
113 
114  TIQuery<Real, Line2<Real>, AlignedBox2<Real>>::DoQuery(segOrigin,
115  segDirection, boxExtent, result);
116 }
117 
118 template <typename Real>
121  Segment2<Real> const& segment, AlignedBox2<Real> const& box)
122 {
123  // Get the centered form of the aligned box. The axes are implicitly
124  // Axis[d] = Vector2<Real>::Unit(d).
125  Vector2<Real> boxCenter, boxExtent;
126  box.GetCenteredForm(boxCenter, boxExtent);
127 
128  // Transform the segment to a centered form in the aligned-box coordinate
129  // system.
130  Vector2<Real> transformedP0 = segment.p[0] - boxCenter;
131  Vector2<Real> transformedP1 = segment.p[1] - boxCenter;
132  Segment2<Real> transformedSegment(transformedP0, transformedP1);
133  Vector2<Real> segOrigin, segDirection;
134  Real segExtent;
135  transformedSegment.GetCenteredForm(segOrigin, segDirection, segExtent);
136 
137  Result result;
138  DoQuery(segOrigin, segDirection, segExtent, boxExtent, result);
139  for (int i = 0; i < result.numIntersections; ++i)
140  {
141  // Compute the segment in the aligned-box coordinate system and then
142  // translate it back to the original coordinates using the box cener.
143  result.point[i] = boxCenter + (segOrigin + result.parameter[i] * segDirection);
144  result.cdeParameter[i] = result.parameter[i];
145 
146  // Convert the parameters from the centered form to the endpoint form.
147  result.parameter[i] = (result.parameter[i] / segExtent + (Real)1) * (Real)0.5;
148  }
149  return result;
150 }
151 
152 template <typename Real>
154  Vector2<Real> const& segOrigin, Vector2<Real> const& segDirection,
155  Real segExtent, Vector2<Real> const& boxExtent, Result& result)
156 {
157  FIQuery<Real, Line2<Real>, AlignedBox2<Real>>::DoQuery(segOrigin,
158  segDirection, boxExtent, result);
159 
160  if (result.intersect)
161  {
162  // The line containing the segment intersects the box; the t-interval
163  // is [t0,t1]. The segment intersects the box as long as [t0,t1]
164  // overlaps the segment t-interval [-segExtent,+segExtent].
165  std::array<Real, 2> segInterval = { -segExtent, segExtent };
166  FIQuery<Real, std::array<Real, 2>, std::array<Real, 2>> iiQuery;
167  auto iiResult = iiQuery(result.parameter, segInterval);
168  result.intersect = iiResult.intersect;
169  result.numIntersections = iiResult.numIntersections;
170  result.parameter = iiResult.overlap;
171  }
172 }
173 
174 
175 }
Result operator()(Type0 const &primitive0, Type1 const &primitive1)
GLuint64EXT * result
Definition: glext.h:10003
void GetCenteredForm(Vector< N, Real > &center, Vector< N, Real > &direction, Real &extent) const
Definition: GteSegment.h:103


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