GteIntrOrientedBox2Sector2.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/GteSector2.h>
14 #include <Mathematics/GteTIQuery.h>
15 
16 // The OrientedBox2 object is considered to be a solid.
17 
18 namespace gte
19 {
20 
21 template <typename Real>
22 class TIQuery<Real, OrientedBox2<Real>, Sector2<Real>>
23 {
24 public:
25  struct Result
26  {
27  bool intersect;
28  };
29 
30  Result operator()(OrientedBox2<Real> const& box, Sector2<Real> const& sector);
31 };
32 
33 template <typename Real>
36  OrientedBox2<Real> const& box, Sector2<Real> const& sector)
37 {
38  Result result;
39 
40  // Determine whether the vertex is inside the box.
41  Vector2<Real> CmV = box.center - sector.vertex;
42  Vector2<Real> P{ Dot(box.axis[0], CmV), Dot(box.axis[1], CmV) };
43  if (fabs(P[0]) <= box.extent[0] && fabs(P[1]) <= box.extent[1])
44  {
45  // The vertex is inside the box.
46  result.intersect = true;
47  return result;
48  }
49 
50  // Test whether the box is outside the right ray boundary of the sector.
51  Vector2<Real> U0
52  {
53  +sector.cosAngle * sector.direction[0] + sector.sinAngle * sector.direction[1],
54  -sector.sinAngle * sector.direction[0] + sector.cosAngle * sector.direction[1]
55  };
56  Vector2<Real> N0 = Perp(U0);
57  Real prjcen0 = Dot(N0, CmV);
58  Real radius0 = box.extent[0] * fabs(Dot(N0, box.axis[0]))
59  + box.extent[1] * fabs(Dot(N0, box.axis[1]));
60  if (prjcen0 > radius0)
61  {
62  result.intersect = false;
63  return result;
64  }
65 
66  // Test whether the box is outside the ray of the left boundary of the
67  // sector.
68  Vector2<Real> U1
69  {
70  +sector.cosAngle * sector.direction[0] - sector.sinAngle * sector.direction[1],
71  +sector.sinAngle * sector.direction[0] + sector.cosAngle * sector.direction[1]
72  };
73  Vector2<Real> N1 = -Perp(U1);
74  Real prjcen1 = Dot(N1, CmV);
75  Real radius1 = box.extent[0] * fabs(Dot(N1, box.axis[0]))
76  + box.extent[1] * fabs(Dot(N1, box.axis[1]));
77  if (prjcen1 > radius1)
78  {
79  result.intersect = false;
80  return result;
81  }
82 
83  // Initialize the polygon of intersection to be the box.
84  Vector2<Real> e0U0 = box.extent[0] * box.axis[0];
85  Vector2<Real> e1U1 = box.extent[1] * box.axis[1];
86  std::vector<Vector2<Real>> polygon;
87  polygon.reserve(8);
88  polygon.push_back(box.center - e0U0 - e1U1);
89  polygon.push_back(box.center + e0U0 - e1U1);
90  polygon.push_back(box.center + e0U0 + e1U1);
91  polygon.push_back(box.center - e0U0 + e1U1);
92 
93  FIQuery<Real, Halfspace<2, Real>, std::vector<Vector2<Real>>> hpQuery;
94  typename FIQuery<Real, Halfspace<2, Real>, std::vector<Vector2<Real>>>::Result hpResult;
95  Halfspace<2, Real> halfspace;
96 
97  // Clip the box against the right-ray sector boundary.
98  if (prjcen0 >= -radius0)
99  {
100  halfspace.normal = -N0;
101  halfspace.constant = Dot(halfspace.normal, sector.vertex);
102  hpResult = hpQuery(halfspace, polygon);
103  polygon = std::move(hpResult.polygon);
104  }
105 
106  // Clip the box against the left-ray sector boundary.
107  if (prjcen1 >= -radius1)
108  {
109  halfspace.normal = -N1;
110  halfspace.constant = Dot(halfspace.normal, sector.vertex);
111  hpResult = hpQuery(halfspace, polygon);
112  polygon = std::move(hpResult.polygon);
113  }
114 
116  typename DCPQuery<Real, Vector2<Real>, Segment2<Real>>::Result psResult;
117  int const numVertices = static_cast<int>(polygon.size());
118  if (numVertices >= 2)
119  {
120  for (int i0 = numVertices - 1, i1 = 0; i1 < numVertices; i0 = i1++)
121  {
122  Segment2<Real> segment(polygon[i0], polygon[i1]);
123  psResult = psQuery(sector.vertex, segment);
124  if (psResult.distance <= sector.radius)
125  {
126  result.intersect = true;
127  return result;
128  }
129  }
130  }
131 
132  result.intersect = false;
133  return result;
134 }
135 
136 }
DualQuaternion< Real > Dot(DualQuaternion< Real > const &d0, DualQuaternion< Real > const &d1)
Vector< N, Real > normal
Definition: GteHalfspace.h:31
Vector2< Real > Perp(Vector2< Real > const &v)
Definition: GteVector2.h:103
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