GteIntrHalfspace2Polygon2.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>
13 #include <Mathematics/GteFIQuery.h>
14 #include <vector>
15 
16 // The queries consider the box to be a solid and the polygon to be a
17 // convex solid.
18 
19 namespace gte
20 {
21 
22 template <typename Real>
23 class FIQuery<Real, Halfspace<2, Real>, std::vector<Vector2<Real>>>
24 {
25 public:
26  struct Result
27  {
28  bool intersect;
29 
30  // If 'intersect' is true, the halfspace and polygon intersect in a
31  // convex polygon.
32  std::vector<Vector2<Real>> polygon;
33  };
34 
35  Result operator()(Halfspace<2, Real> const& halfspace,
36  std::vector<Vector2<Real>> const& polygon);
37 };
38 
39 
40 template <typename Real>
41 typename FIQuery<Real, Halfspace<2, Real>, std::vector<Vector2<Real>>>::Result
42 FIQuery<Real, Halfspace<2, Real>, std::vector<Vector2<Real>>>::operator()(
43  Halfspace<2, Real> const& halfspace, std::vector<Vector2<Real>> const& polygon)
44 {
45  Result result;
46 
47  // Determine whether the polygon vertices are outside the halfspace,
48  // inside the halfspace, or on the halfspace boundary.
49  int const numVertices = static_cast<int>(polygon.size());
50  std::vector<Real> distance(numVertices);
51  int positive = 0, negative = 0, positiveIndex = -1;
52  for (int i = 0; i < numVertices; ++i)
53  {
54  distance[i] = Dot(halfspace.normal, polygon[i]) - halfspace.constant;
55  if (distance[i] > (Real)0)
56  {
57  ++positive;
58  if (positiveIndex == -1)
59  {
60  positiveIndex = i;
61  }
62  }
63  else if (distance[i] < (Real)0)
64  {
65  ++negative;
66  }
67  }
68 
69  if (positive == 0)
70  {
71  // The polygon is strictly outside the halfspace.
72  result.intersect = false;
73  return result;
74  }
75 
76  if (negative == 0)
77  {
78  // The polygon is contained in the closed halfspace, so it is
79  // fully visible and no clipping is necessary.
80  result.intersect = true;
81  return result;
82  }
83 
84  // The line transversely intersects the polygon. Clip the polygon.
85  Vector2<Real> vertex;
86  int curr, prev;
87  Real t;
88 
89  if (positiveIndex > 0)
90  {
91  // Compute the first clip vertex on the line.
92  curr = positiveIndex;
93  prev = curr - 1;
94  t = distance[curr] / (distance[curr] - distance[prev]);
95  vertex = polygon[curr] + t * (polygon[prev] - polygon[curr]);
96  result.polygon.push_back(vertex);
97 
98  // Include the vertices on the positive side of line.
99  while (curr < numVertices && distance[curr] >(Real)0)
100  {
101  result.polygon.push_back(polygon[curr++]);
102  }
103 
104  // Compute the kast clip vertex on the line.
105  if (curr < numVertices)
106  {
107  prev = curr - 1;
108  }
109  else
110  {
111  curr = 0;
112  prev = numVertices - 1;
113  }
114  t = distance[curr] / (distance[curr] - distance[prev]);
115  vertex = polygon[curr] + t * (polygon[prev] - polygon[curr]);
116  result.polygon.push_back(vertex);
117  }
118  else // positiveIndex is 0
119  {
120  // Include the vertices on the positive side of line.
121  curr = 0;
122  while (curr < numVertices && distance[curr] >(Real)0)
123  {
124  result.polygon.push_back(polygon[curr++]);
125  }
126 
127  // Compute the last clip vertex on the line.
128  prev = curr - 1;
129  t = distance[curr] / (distance[curr] - distance[prev]);
130  vertex = polygon[curr] + t * (polygon[prev] - polygon[curr]);
131  result.polygon.push_back(vertex);
132 
133  // Skip the vertices on the negative side of the line.
134  while (curr < numVertices && distance[curr] <= (Real)0)
135  {
136  curr++;
137  }
138 
139  // Compute the first clip vertex on the line.
140  if (curr < numVertices)
141  {
142  prev = curr - 1;
143  t = distance[curr] / (distance[curr] - distance[prev]);
144  vertex = polygon[curr] + t * (polygon[prev] - polygon[curr]);
145  result.polygon.push_back(vertex);
146 
147  // Keep the vertices on the positive side of the line.
148  while (curr < numVertices && distance[curr] >(Real)0)
149  {
150  result.polygon.push_back(polygon[curr++]);
151  }
152  }
153  else
154  {
155  curr = 0;
156  prev = numVertices - 1;
157  t = distance[curr] / (distance[curr] - distance[prev]);
158  vertex = polygon[curr] + t * (polygon[prev] - polygon[curr]);
159  result.polygon.push_back(vertex);
160  }
161  }
162 
163  result.intersect = true;
164  return result;
165 }
166 
167 }
Result operator()(Type0 const &primitive0, Type1 const &primitive1)
GLsizei GLsizei GLfloat distance
Definition: glext.h:9704
DualQuaternion< Real > Dot(DualQuaternion< Real > const &d0, DualQuaternion< Real > const &d1)
GLdouble GLdouble t
Definition: glext.h:239
GLuint64EXT * result
Definition: glext.h:10003


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