GteContPointInPolygon2.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 
12 // Given a polygon as an order list of vertices (x[i],y[i]) for 0 <= i < N
13 // and a test point (xt,yt), return 'true' if (xt,yt) is in the polygon and
14 // 'false' if it is not. All queries require that the number of vertices
15 // satisfies N >= 3.
16 
17 namespace gte
18 {
19 
20 template <typename Real>
22 {
23 public:
24  // The class object stores a copy of 'points', so be careful about the
25  // persistence of 'points' when you have created a PointInPolygon2 object.
26  PointInPolygon2(int numPoints, Vector2<Real> const* points);
27 
28  // Simple polygons (ray-intersection counting).
29  bool Contains(Vector2<Real> const& p) const;
30 
31  // Algorithms for convex polygons. The input polygons must have vertices
32  // in counterclockwise order.
33 
34  // O(N) algorithm (which-side-of-edge tests)
35  bool ContainsConvexOrderN(Vector2<Real> const& p) const;
36 
37  // O(log N) algorithm (bisection and recursion, like BSP tree)
38  bool ContainsConvexOrderLogN(Vector2<Real> const& p) const;
39 
40  // The polygon must have exactly four vertices. This method is like the
41  // O(log N) and uses three which-side-of-segment test instead of four
42  // which-side-of-edge tests. If the polygon does not have four vertices,
43  // the function returns false.
44  bool ContainsQuadrilateral(Vector2<Real> const& p) const;
45 
46 private:
47  // For recursion in ContainsConvexOrderLogN.
48  bool SubContainsPoint(Vector2<Real> const& p, int i0, int i1) const;
49 
52 };
53 
54 
55 template <typename Real>
57  Vector2<Real> const* points)
58  :
59  mNumPoints(numPoints),
60  mPoints(points)
61 {
62 }
63 
64 template <typename Real>
66 {
67  bool inside = false;
68  for (int i = 0, j = mNumPoints - 1; i < mNumPoints; j = i++)
69  {
70  Vector2<Real> const& U0 = mPoints[i];
71  Vector2<Real> const& U1 = mPoints[j];
72  Real rhs, lhs;
73 
74  if (p[1] < U1[1]) // U1 above ray
75  {
76  if (U0[1] <= p[1]) // U0 on or below ray
77  {
78  lhs = (p[1] - U0[1])*(U1[0] - U0[0]);
79  rhs = (p[0] - U0[0])*(U1[1] - U0[1]);
80  if (lhs > rhs)
81  {
82  inside = !inside;
83  }
84  }
85  }
86  else if (p[1] < U0[1]) // U1 on or below ray, U0 above ray
87  {
88  lhs = (p[1] - U0[1])*(U1[0] - U0[0]);
89  rhs = (p[0] - U0[0])*(U1[1] - U0[1]);
90  if (lhs < rhs)
91  {
92  inside = !inside;
93  }
94  }
95  }
96  return inside;
97 }
98 
99 template <typename Real>
101 {
102  for (int i1 = 0, i0 = mNumPoints - 1; i1 < mNumPoints; i0 = i1++)
103  {
104  Real nx = mPoints[i1][1] - mPoints[i0][1];
105  Real ny = mPoints[i0][0] - mPoints[i1][0];
106  Real dx = p[0] - mPoints[i0][0];
107  Real dy = p[1] - mPoints[i0][1];
108  if (nx*dx + ny*dy >(Real)0)
109  {
110  return false;
111  }
112  }
113  return true;
114 }
115 
116 template <typename Real>
118 const
119 {
120  return SubContainsPoint(p, 0, 0);
121 }
122 
123 template <typename Real>
125 const
126 {
127  if (mNumPoints != 4)
128  {
129  return false;
130  }
131 
132  Real nx = mPoints[2][1] - mPoints[0][1];
133  Real ny = mPoints[0][0] - mPoints[2][0];
134  Real dx = p[0] - mPoints[0][0];
135  Real dy = p[1] - mPoints[0][1];
136 
137  if (nx*dx + ny*dy > (Real)0)
138  {
139  // P potentially in <V0,V1,V2>
140  nx = mPoints[1][1] - mPoints[0][1];
141  ny = mPoints[0][0] - mPoints[1][0];
142  if (nx*dx + ny*dy > (Real)0.0)
143  {
144  return false;
145  }
146 
147  nx = mPoints[2][1] - mPoints[1][1];
148  ny = mPoints[1][0] - mPoints[2][0];
149  dx = p[0] - mPoints[1][0];
150  dy = p[1] - mPoints[1][1];
151  if (nx*dx + ny*dy > (Real)0)
152  {
153  return false;
154  }
155  }
156  else
157  {
158  // P potentially in <V0,V2,V3>
159  nx = mPoints[0][1] - mPoints[3][1];
160  ny = mPoints[3][0] - mPoints[0][0];
161  if (nx*dx + ny*dy > (Real)0)
162  {
163  return false;
164  }
165 
166  nx = mPoints[3][1] - mPoints[2][1];
167  ny = mPoints[2][0] - mPoints[3][0];
168  dx = p[0] - mPoints[3][0];
169  dy = p[1] - mPoints[3][1];
170  if (nx*dx + ny*dy > (Real)0)
171  {
172  return false;
173  }
174  }
175  return true;
176 }
177 
178 template <typename Real>
180  int i1) const
181 {
182  Real nx, ny, dx, dy;
183 
184  int diff = i1 - i0;
185  if (diff == 1 || (diff < 0 && diff + mNumPoints == 1))
186  {
187  nx = mPoints[i1][1] - mPoints[i0][1];
188  ny = mPoints[i0][0] - mPoints[i1][0];
189  dx = p[0] - mPoints[i0][0];
190  dy = p[1] - mPoints[i0][1];
191  return nx*dx + ny*dy <= (Real)0;
192  }
193 
194  // Bisect the index range.
195  int mid;
196  if (i0 < i1)
197  {
198  mid = (i0 + i1) >> 1;
199  }
200  else
201  {
202  mid = ((i0 + i1 + mNumPoints) >> 1);
203  if (mid >= mNumPoints)
204  {
205  mid -= mNumPoints;
206  }
207  }
208 
209  // Determine which side of the splitting line contains the point.
210  nx = mPoints[mid][1] - mPoints[i0][1];
211  ny = mPoints[i0][0] - mPoints[mid][0];
212  dx = p[0] - mPoints[i0][0];
213  dy = p[1] - mPoints[i0][1];
214  if (nx*dx + ny*dy > (Real)0)
215  {
216  // P potentially in <V(i0),V(i0+1),...,V(mid-1),V(mid)>
217  return SubContainsPoint(p, i0, mid);
218  }
219  else
220  {
221  // P potentially in <V(mid),V(mid+1),...,V(i1-1),V(i1)>
222  return SubContainsPoint(p, mid, i1);
223  }
224 }
225 
226 
227 }
PointInPolygon2(int numPoints, Vector2< Real > const *points)
bool Contains(Vector2< Real > const &p) const
bool ContainsQuadrilateral(Vector2< Real > const &p) const
GLfixed GLfixed GLint GLint GLfixed points
Definition: glext.h:4927
bool ContainsConvexOrderLogN(Vector2< Real > const &p) const
bool ContainsConvexOrderN(Vector2< Real > const &p) const
Vector2< Real > const * mPoints
GLbyte nx
Definition: glext.h:6082
bool SubContainsPoint(Vector2< Real > const &p, int i0, int i1) const
GLfixed ny
Definition: glext.h:4889
GLfloat GLfloat p
Definition: glext.h:11668


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 03:59:59