GteSeparatePoints2.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 
11 
12 // Separate two point sets, if possible, by computing a line for which the
13 // point sets lie on opposite sides. The algorithm computes the convex hull
14 // of the point sets, then uses the method of separating axes to determine if
15 // the two convex polygons are disjoint. The ComputeType is for the
16 // ConvexHull2 class.
17 
18 namespace gte
19 {
20 
21 template <typename Real, typename ComputeType>
23 {
24 public:
25  // The return value is 'true' if and only if there is a separation. If
26  // 'true', the returned line is a separating line. The code assumes that
27  // each point set has at least 3 noncollinear points.
28  bool operator()(int numPoints0, Vector2<Real> const* points0,
29  int numPoints1, Vector2<Real> const* points1,
30  Line2<Real>& separatingLine) const;
31 
32 private:
33  int OnSameSide(Vector2<Real> const& lineNormal, Real lineConstant,
34  int numEdges, int const* edges, Vector2<Real> const* points) const;
35 
36  int WhichSide(Vector2<Real> const& lineNormal, Real lineConstant,
37  int numEdges, int const* edges, Vector2<Real> const* points) const;
38 };
39 
40 
41 template <typename Real, typename ComputeType>
43  Vector2<Real> const* points0, int numPoints1,
44  Vector2<Real> const* points1, Line2<Real>& separatingLine) const
45 {
46  // Construct convex hull of point set 0.
48  ch0(numPoints0, points0, (Real)0);
49  if (ch0.GetDimension() != 2)
50  {
51  return false;
52  }
53 
54  // Construct convex hull of point set 1.
56  ch1(numPoints1, points1, (Real)0);
57  if (ch1.GetDimension() != 2)
58  {
59  return false;
60  }
61 
62  int numEdges0 = static_cast<int>(ch0.GetHull().size());
63  int const* edges0 = &ch0.GetHull()[0];
64  int numEdges1 = static_cast<int>(ch1.GetHull().size());
65  int const* edges1 = &ch1.GetHull()[0];
66 
67  // Test edges of hull 0 for possible separation of points.
68  int j0, j1, i0, i1, side0, side1;
69  Vector2<Real> lineNormal;
70  Real lineConstant;
71  for (j1 = 0, j0 = numEdges0 - 1; j1 < numEdges0; j0 = j1++)
72  {
73  // Look up edge (assert: i0 != i1 ).
74  i0 = edges0[j0];
75  i1 = edges0[j1];
76 
77  // Compute potential separating line (assert: (xNor,yNor) != (0,0)).
78  separatingLine.origin = points0[i0];
79  separatingLine.direction = points0[i1] - points0[i0];
80  Normalize(separatingLine.direction);
81  lineNormal = Perp(separatingLine.direction);
82  lineConstant = Dot(lineNormal, separatingLine.origin);
83 
84  // Determine whether hull 1 is on same side of line.
85  side1 = OnSameSide(lineNormal, lineConstant, numEdges1, edges1,
86  points1);
87 
88  if (side1)
89  {
90  // Determine on which side of line hull 0 lies.
91  side0 = WhichSide(lineNormal, lineConstant, numEdges0,
92  edges0, points0);
93 
94  if (side0*side1 <= 0) // Line separates hulls.
95  {
96  return true;
97  }
98  }
99  }
100 
101  // Test edges of hull 1 for possible separation of points.
102  for (j1 = 0, j0 = numEdges1 - 1; j1 < numEdges1; j0 = j1++)
103  {
104  // Look up edge (assert: i0 != i1 ).
105  i0 = edges1[j0];
106  i1 = edges1[j1];
107 
108  // Compute perpendicular to edge (assert: (xNor,yNor) != (0,0)).
109  separatingLine.origin = points1[i0];
110  separatingLine.direction = points1[i1] - points1[i0];
111  Normalize(separatingLine.direction);
112  lineNormal = Perp(separatingLine.direction);
113  lineConstant = Dot(lineNormal, separatingLine.origin);
114 
115  // Determine whether hull 0 is on same side of line.
116  side0 = OnSameSide(lineNormal, lineConstant, numEdges0, edges0,
117  points0);
118 
119  if (side0)
120  {
121  // Determine on which side of line hull 1 lies.
122  side1 = WhichSide(lineNormal, lineConstant, numEdges1,
123  edges1, points1);
124 
125  if (side0*side1 <= 0) // Line separates hulls.
126  {
127  return true;
128  }
129  }
130  }
131 
132  return false;
133 }
134 
135 template <typename Real, typename ComputeType>
137  Vector2<Real> const& lineNormal, Real lineConstant, int numEdges,
138  int const* edges, Vector2<Real> const* points) const
139 {
140  // Test whether all points on same side of line Dot(N,X) = c.
141  Real c0;
142  int posSide = 0, negSide = 0;
143 
144  for (int i1 = 0, i0 = numEdges - 1; i1 < numEdges; i0 = i1++)
145  {
146  c0 = Dot(lineNormal, points[edges[i0]]);
147  if (c0 > lineConstant)
148  {
149  ++posSide;
150  }
151  else if (c0 < lineConstant)
152  {
153  ++negSide;
154  }
155 
156  if (posSide && negSide)
157  {
158  // Line splits point set.
159  return 0;
160  }
161 
162  c0 = Dot(lineNormal, points[edges[i1]]);
163  if (c0 > lineConstant)
164  {
165  ++posSide;
166  }
167  else if (c0 < lineConstant)
168  {
169  ++negSide;
170  }
171 
172  if (posSide && negSide)
173  {
174  // Line splits point set.
175  return 0;
176  }
177  }
178 
179  return (posSide ? +1 : -1);
180 }
181 
182 template <typename Real, typename ComputeType>
184  Vector2<Real> const& lineNormal, Real lineConstant, int numEdges,
185  int const* edges, Vector2<Real> const* points) const
186 {
187  // Establish which side of line hull is on.
188  Real c0;
189  for (int i1 = 0, i0 = numEdges - 1; i1 < numEdges; i0 = i1++)
190  {
191  c0 = Dot(lineNormal, points[edges[i0]]);
192  if (c0 > lineConstant)
193  {
194  // Hull on positive side.
195  return +1;
196  }
197  if (c0 < lineConstant)
198  {
199  // Hull on negative side.
200  return -1;
201  }
202 
203  c0 = Dot(lineNormal, points[edges[i1]]);
204  if (c0 > lineConstant)
205  {
206  // Hull on positive side.
207  return +1;
208  }
209  if (c0 < lineConstant)
210  {
211  // Hull on negative side.
212  return -1;
213  }
214  }
215 
216  // Hull is effectively collinear.
217  return 0;
218 }
219 
220 
221 }
std::vector< int > const & GetHull() const
int WhichSide(Vector2< Real > const &lineNormal, Real lineConstant, int numEdges, int const *edges, Vector2< Real > const *points) const
Vector< N, Real > direction
Definition: GteLine.h:29
GLfixed GLfixed GLint GLint GLfixed points
Definition: glext.h:4927
int OnSameSide(Vector2< Real > const &lineNormal, Real lineConstant, int numEdges, int const *edges, Vector2< Real > const *points) const
int GetDimension() const
DualQuaternion< Real > Dot(DualQuaternion< Real > const &d0, DualQuaternion< Real > const &d1)
Real Normalize(GVector< Real > &v, bool robust=false)
Definition: GteGVector.h:454
Vector2< Real > Perp(Vector2< Real > const &v)
Definition: GteVector2.h:103
Vector< N, Real > origin
Definition: GteLine.h:29
bool operator()(int numPoints0, Vector2< Real > const *points0, int numPoints1, Vector2< Real > const *points1, Line2< Real > &separatingLine) const


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