LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
Polygon2D Class Reference

#include "Polygon2D.h"

Public Member Functions

 Polygon2D ()
 
 Polygon2D (const std::vector< std::pair< float, float >> &points)
 
 Polygon2D (const Polygon2D &poly1, const Polygon2D &poly2)
 
unsigned int Size () const
 Create Intersection Polygon. More...
 
const std::pair< float, float > & Point (unsigned int p) const
 
std::pair< float, float > Project (const std::pair< float, float > &, float) const
 
float Area () const
 
float Perimeter () const
 
bool Overlap (float slope, const Polygon2D &poly2, const std::pair< float, float > &origin) const
 
bool PolyOverlap (const Polygon2D &poly2) const
 
bool PolyOverlapSegments (const Polygon2D &poly2) const
 
bool PointInside (const std::pair< float, float > &point) const
 
bool Contained (const Polygon2D &poly2) const
 
void UntanglePolygon ()
 check if poly2 is inside poly1 More...
 

Private Attributes

std::vector< std::pair< float, float > > vertices
 

Detailed Description

Definition at line 32 of file Polygon2D.h.

Constructor & Destructor Documentation

Polygon2D::Polygon2D ( )
inline

Definition at line 38 of file Polygon2D.h.

Referenced by Polygon2D().

38 {}
Polygon2D::Polygon2D ( const std::vector< std::pair< float, float >> &  points)
inline

Definition at line 39 of file Polygon2D.h.

References Polygon2D().

39 { vertices = points; }
std::vector< std::pair< float, float > > vertices
Definition: Polygon2D.h:35
Polygon2D::Polygon2D ( const Polygon2D poly1,
const Polygon2D poly2 
)

Definition at line 63 of file Polygon2D.cxx.

References GetIntersection(), Point(), PointInside(), PolyOverlap(), SegmentOverlap(), Size(), and vertices.

64 {
65 
66  //figure out if the two polygons overlap at all
67  if (!(poly1.PolyOverlap(poly2))) {
68  std::vector<std::pair<float, float>> nullpoint;
69  vertices = nullpoint;
70  return;
71  }
72 
73  //The overlap polygon is made up by:
74  //1) all points of poly1 in poly2
75  //2) all points of poly2 in poly1
76  //3) all intersection points between segments
77 
78  //make a new set of points and add points
79  //as listed above, if found.
80  std::vector<std::pair<float, float>> IntersectionPoints;
81  //1)
82  for (unsigned int p1 = 0; p1 < poly1.Size(); p1++) {
83  if (poly2.PointInside(poly1.Point(p1))) { IntersectionPoints.push_back(poly1.Point(p1)); }
84  }
85  //2)
86  for (unsigned int p2 = 0; p2 < poly2.Size(); p2++) {
87  if (poly1.PointInside(poly2.Point(p2))) { IntersectionPoints.push_back(poly2.Point(p2)); }
88  }
89  //3)
90  //FIND SEGMENT INTERSECTIONS
91  for (unsigned int i = 0; i < poly1.Size(); i++) {
92  for (unsigned int j = 0; j < poly2.Size(); j++) {
93  if (SegmentOverlap(poly1.Point(i).first,
94  poly1.Point(i).second,
95  poly1.Point(i + 1).first,
96  poly1.Point(i + 1).second,
97  poly2.Point(j).first,
98  poly2.Point(j).second,
99  poly2.Point(j + 1).first,
100  poly2.Point(j + 1).second))
101  //segments overlap...add intersection to list
102  IntersectionPoints.push_back(GetIntersection(poly1.Point(i).first,
103  poly1.Point(i).second,
104  poly1.Point(i + 1).first,
105  poly1.Point(i + 1).second,
106  poly2.Point(j).first,
107  poly2.Point(j).second,
108  poly2.Point(j + 1).first,
109  poly2.Point(j + 1).second));
110  } //for all segments in poly2
111  } //for all segments in poly1
112 
113  vertices = IntersectionPoints;
114  return;
115 }
const std::pair< float, float > & Point(unsigned int p) const
Definition: Polygon2D.cxx:158
unsigned int Size() const
Create Intersection Polygon.
Definition: Polygon2D.h:41
std::vector< std::pair< float, float > > vertices
Definition: Polygon2D.h:35
std::pair< float, float > GetIntersection(double Ax, double Ay, double Bx, double By, double Cx, double Cy, double Dx, double Dy)
Definition: Polygon2D.cxx:36
bool SegmentOverlap(double Ax, double Ay, double Bx, double By, double Cx, double Cy, double Dx, double Dy)
Definition: Polygon2D.cxx:20
bool PointInside(const std::pair< float, float > &point) const
Definition: Polygon2D.cxx:271
bool PolyOverlap(const Polygon2D &poly2) const
Definition: Polygon2D.cxx:221

Member Function Documentation

float Polygon2D::Area ( ) const

Definition at line 118 of file Polygon2D.cxx.

References vertices.

Referenced by Size().

119 {
120  //how? here:
121  //http://www.mathsisfun.com/geometry/area-irregular-polygons.html
122  float area = 0;
123  for (unsigned int i = 0; i < vertices.size(); i++) {
124  if (i < (vertices.size() - 1))
125  area += (((vertices.at(i)).second) + ((vertices.at(i + 1)).second)) *
126  (((vertices.at(i)).first) - ((vertices.at(i + 1)).first)) * 0.5;
127  if (i == (vertices.size() - 1))
128  area += (((vertices.at(i)).second) + ((vertices.at(0)).second)) *
129  (((vertices.at(i)).first) - ((vertices.at(0)).first)) * 0.5;
130  }
131  if (area < 0.0) area = -area;
132  return area;
133 }
std::vector< std::pair< float, float > > vertices
Definition: Polygon2D.h:35
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:82
bool Polygon2D::Contained ( const Polygon2D poly2) const

Definition at line 296 of file Polygon2D.cxx.

References Point(), PointInside(), and Size().

Referenced by PolyOverlapSegments(), and Size().

297 {
298 
299  //loop over poly2 checking wehther
300  //points of poly2 all inside poly1
301  for (unsigned int i = 0; i < poly2.Size(); i++) {
302  if (!(this->PointInside(poly2.Point(i)))) return false;
303  }
304 
305  return true;
306 }
const std::pair< float, float > & Point(unsigned int p) const
Definition: Polygon2D.cxx:158
unsigned int Size() const
Create Intersection Polygon.
Definition: Polygon2D.h:41
bool PointInside(const std::pair< float, float > &point) const
Definition: Polygon2D.cxx:271
bool Polygon2D::Overlap ( float  slope,
const Polygon2D poly2,
const std::pair< float, float > &  origin 
) const

Definition at line 199 of file Polygon2D.cxx.

References Project().

Referenced by PolyOverlap(), and Size().

202 {
203  //translate and rotate both polygons
204  float theta = tan(slope);
205  //here we translate origin, rotate and find x-coordinates and find range of projection on edge line
206  std::pair<float, float> range1 = this->Project(origin, theta);
207  std::pair<float, float> range2 = poly2.Project(origin, theta);
208  //std::cout << "range 1: " << range1.first << " " << range1.second << std::endl;
209  //std::cout << "range 2: " << range2.first << " " << range2.second << std::endl;
210  //if the two projections don't overlap --> no overlap!
211  if ((((range1.first <= range2.second) and (range1.first >= range2.first)) or
212  ((range1.second <= range2.second) and (range1.second >= range2.first))) or
213  (((range2.first <= range1.second) and (range2.first >= range1.first)) or
214  ((range2.second <= range1.second) and (range2.second >= range1.first))))
215  return true; //yes...they overlap
216  else
217  return false; //no....they do not overlap
218 }
std::pair< float, float > Project(const std::pair< float, float > &, float) const
Definition: Polygon2D.cxx:175
constexpr Point origin()
Returns a origin position with a point of the specified type.
Definition: geo_vectors.h:229
float Polygon2D::Perimeter ( ) const

Definition at line 136 of file Polygon2D.cxx.

References vertices.

Referenced by Size().

137 {
138 
139  float perimeter = 0.;
140 
141  for (unsigned int i = 0; i < vertices.size(); i++) {
142  if (i < (vertices.size() - 1))
143  perimeter += ((vertices.at(i).second - vertices.at(i + 1).second) *
144  (vertices.at(i).second - vertices.at(i + 1).second) +
145  (vertices.at(i).first - vertices.at(i + 1).first) *
146  (vertices.at(i).first - vertices.at(i + 1).first));
147  if (i == (vertices.size() - 1))
148  perimeter += ((vertices.at(i).second - vertices.at(0).second) *
149  (vertices.at(i).second - vertices.at(0).second) +
150  (vertices.at(i).first - vertices.at(0).first) *
151  (vertices.at(i).first - vertices.at(0).first));
152  }
153 
154  return sqrt(perimeter);
155 }
std::vector< std::pair< float, float > > vertices
Definition: Polygon2D.h:35
const std::pair< float, float > & Polygon2D::Point ( unsigned int  p) const

Definition at line 158 of file Polygon2D.cxx.

References vertices.

Referenced by Contained(), PointInside(), Polygon2D(), PolyOverlap(), PolyOverlapSegments(), and Size().

159 {
160  //This function returns the vertex under consideration
161  //as a std::pair<float,float> Returns vertex for argument
162  //from 0 to N-1. For input N = number of sides then
163  //the first vertex is returned
164  if (p < vertices.size())
165  return vertices.at(p);
166  else if (p == vertices.size())
167  return vertices.at(0);
168  else {
169  std::cout << "Out of bounds of Polygon!" << std::endl;
170  return vertices.at(0);
171  }
172 }
std::vector< std::pair< float, float > > vertices
Definition: Polygon2D.h:35
bool Polygon2D::PointInside ( const std::pair< float, float > &  point) const

Definition at line 271 of file Polygon2D.cxx.

References Point(), SegmentOverlap(), and Size().

Referenced by cmtool::CBAlgoCenterOfMass::Bool(), cmtool::CBAlgoCenterOfMassSmall::Bool(), Contained(), Polygon2D(), and Size().

272 {
273 
274  //any ray originating at point will cross polygon
275  //even number of times if point outside
276  //odd number of times if point inside
277  int intersections = 0;
278  for (unsigned int i = 0; i < this->Size(); i++) {
279  if (SegmentOverlap(this->Point(i).first,
280  this->Point(i).second,
281  this->Point(i + 1).first,
282  this->Point(i + 1).second,
283  10000.0,
284  10000.0,
285  point.first,
286  point.second))
287  intersections += 1;
288  }
289  if ((intersections % 2) == 0)
290  return false;
291  else
292  return true;
293 }
const std::pair< float, float > & Point(unsigned int p) const
Definition: Polygon2D.cxx:158
unsigned int Size() const
Create Intersection Polygon.
Definition: Polygon2D.h:41
bool SegmentOverlap(double Ax, double Ay, double Bx, double By, double Cx, double Cy, double Dx, double Dy)
Definition: Polygon2D.cxx:20
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:82
bool Polygon2D::PolyOverlap ( const Polygon2D poly2) const

Definition at line 221 of file Polygon2D.cxx.

References FindSlope(), Overlap(), Point(), and Size().

Referenced by Polygon2D(), and Size().

222 {
223 
224  //start from first pair in vector then check all edges.
225  //edges are (0,1), (1,2), ..., (N,N-1) each pair a pair
226  //of vertexes
227  for (unsigned int i = 0; i < this->Size(); i++) { //loop over first polygon's vertices
228  //find projection line's slope
229  //line: y=ax+b --- slope is a variable
230  float slope;
231  slope = FindSlope(this->Point(i), this->Point(i + 1));
232  //if there is even one no-overlap
233  //need to exit and return no overlap!
234  if (!(this->Overlap(slope, poly2, this->Point(i)))) return false;
235  } //loop over first polygon vertices
236 
237  //do the exact same thing but reversing polygon role
238  for (unsigned int i = 0; i < poly2.Size(); i++) { //loop over first polygon
239  float slope;
240  slope = FindSlope(poly2.Point(i), poly2.Point(i + 1));
241  if (!(poly2.Overlap(slope, *this, poly2.Point(i)))) return false;
242  } //loop over second polygon vertices
243  return true;
244 }
const std::pair< float, float > & Point(unsigned int p) const
Definition: Polygon2D.cxx:158
unsigned int Size() const
Create Intersection Polygon.
Definition: Polygon2D.h:41
bool Overlap(float slope, const Polygon2D &poly2, const std::pair< float, float > &origin) const
Definition: Polygon2D.cxx:199
float FindSlope(const std::pair< float, float > &p1, const std::pair< float, float > &p2)
Definition: Polygon2D.cxx:7
bool Polygon2D::PolyOverlapSegments ( const Polygon2D poly2) const

Definition at line 247 of file Polygon2D.cxx.

References Contained(), Point(), SegmentOverlap(), and Size().

Referenced by Size().

248 {
249  //if contained in one another then they also overlap:
250  if ((this->Contained(poly2)) or (poly2.Contained(*this))) { return true; }
251  //loop over the two polygons checking wehther
252  //two segments ever intersect
253  for (unsigned int i = 0; i < this->Size(); i++) {
254  for (unsigned int j = 0; j < poly2.Size(); j++) {
255  if (SegmentOverlap(this->Point(i).first,
256  this->Point(i).second,
257  this->Point(i + 1).first,
258  this->Point(i + 1).second,
259  poly2.Point(j).first,
260  poly2.Point(j).second,
261  poly2.Point(j + 1).first,
262  poly2.Point(j + 1).second)) {
263  return true;
264  }
265  }
266  }
267  return false;
268 }
bool Contained(const Polygon2D &poly2) const
Definition: Polygon2D.cxx:296
const std::pair< float, float > & Point(unsigned int p) const
Definition: Polygon2D.cxx:158
unsigned int Size() const
Create Intersection Polygon.
Definition: Polygon2D.h:41
bool SegmentOverlap(double Ax, double Ay, double Bx, double By, double Cx, double Cy, double Dx, double Dy)
Definition: Polygon2D.cxx:20
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:82
std::pair< float, float > Polygon2D::Project ( const std::pair< float, float > &  p,
float  theta 
) const

Definition at line 175 of file Polygon2D.cxx.

References vertices.

Referenced by Overlap(), and Size().

176 {
177 
178  std::pair<float, float> range(10000, 0);
179  std::pair<float, float> ptmp;
180 
181  for (unsigned int i = 0; i < vertices.size(); i++) {
182  //Translation
183  //translating each vertex so that origin is on first vertex on polygon's edge being considered
184  ptmp = std::make_pair((vertices.at(i)).first - p.first, (vertices.at(i)).second - p.second);
185  //Rotation
186  //instead of rotating each (x,y) edge (slow) just find nex x-position which gives us information
187  //on the projection of that vertex on the line we are considering
188  // +x direction is from vertex in consideration (vertex 'i' in loop) to next vertex
189  //now find the x-coordinate of that vertex after it is rotated such that edge is now + x axis
190  float xnew = (ptmp.first) * cos(theta) + (ptmp.second) * sin(theta);
191  //finally calculate range of projection on x-axis: look at every x position and compare it to range
192  if (xnew < range.first) range.first = xnew;
193  if (xnew > range.second) range.second = xnew;
194  }
195  return range;
196 }
std::vector< std::pair< float, float > > vertices
Definition: Polygon2D.h:35
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:82
unsigned int Polygon2D::Size ( ) const
inline

Create Intersection Polygon.

Definition at line 41 of file Polygon2D.h.

References Area(), Contained(), geo::origin(), Overlap(), Perimeter(), Point(), PointInside(), PolyOverlap(), PolyOverlapSegments(), Project(), and UntanglePolygon().

Referenced by Contained(), PointInside(), Polygon2D(), PolyOverlap(), and PolyOverlapSegments().

41 { return vertices.size(); }
std::vector< std::pair< float, float > > vertices
Definition: Polygon2D.h:35
void Polygon2D::UntanglePolygon ( )

check if poly2 is inside poly1

Definition at line 309 of file Polygon2D.cxx.

References SegmentOverlap(), tmp, and vertices.

Referenced by Size().

310 {
311 
312  //loop over edges
313  for (unsigned int i = 0; i < vertices.size() - 1; i++) {
314  double Ax = vertices.at(i).first;
315  double Ay = vertices.at(i).second;
316  double Bx = vertices.at(i + 1).first;
317  double By = vertices.at(i + 1).second;
318  //loop over edges that have not been checked yet
319  for (unsigned int j = i + 2; j < vertices.size() - 1; j++) {
320  //avoid consecutive segments
321  if (vertices.at(i) == vertices.at(j + 1))
322  continue;
323  else {
324  double Cx = vertices.at(j).first;
325  double Cy = vertices.at(j).second;
326  double Dx = vertices.at(j + 1).first;
327  double Dy = vertices.at(j + 1).second;
328 
329  if (SegmentOverlap(Ax, Ay, Bx, By, Cx, Cy, Dx, Dy)) {
330  std::pair<float, float> tmp = vertices.at(i + 1);
331  vertices.at(i + 1) = vertices.at(j);
332  vertices.at(j) = tmp;
333  //swapped polygon, now do recursion to make sure
334  this->UntanglePolygon();
335  } //if crossing
336  }
337  } //second loop
338  } //first loop
339 }
Float_t tmp
Definition: plot.C:35
std::vector< std::pair< float, float > > vertices
Definition: Polygon2D.h:35
bool SegmentOverlap(double Ax, double Ay, double Bx, double By, double Cx, double Cy, double Dx, double Dy)
Definition: Polygon2D.cxx:20
void UntanglePolygon()
check if poly2 is inside poly1
Definition: Polygon2D.cxx:309

Member Data Documentation

std::vector<std::pair<float, float> > Polygon2D::vertices
private

Definition at line 35 of file Polygon2D.h.

Referenced by Area(), Perimeter(), Point(), Polygon2D(), Project(), and UntanglePolygon().


The documentation for this class was generated from the following files: