LArSoft  v07_13_02
Liquid Argon Software toolkit - http://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 37 of file Polygon2D.h.

Constructor & Destructor Documentation

Polygon2D::Polygon2D ( )
inline

Definition at line 44 of file Polygon2D.h.

Referenced by Polygon2D().

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

Definition at line 45 of file Polygon2D.h.

References Polygon2D().

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

Definition at line 49 of file Polygon2D.cxx.

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

50 {
51 
52  //figure out if the two polygons overlap at all
53  if ( !(poly1.PolyOverlap(poly2)) ){
54  std::vector< std::pair<float,float> > nullpoint;
55  vertices = nullpoint;
56  return;
57  }
58 
59  //The overlap polygon is made up by:
60  //1) all points of poly1 in poly2
61  //2) all points of poly2 in poly1
62  //3) all intersection points between segments
63 
64  //make a new set of points and add points
65  //as listed above, if found.
66  std::vector<std::pair<float,float> > IntersectionPoints;
67  //1)
68  for (unsigned int p1=0; p1 < poly1.Size(); p1++){
69  if ( poly2.PointInside( poly1.Point(p1) ) ) { IntersectionPoints.push_back( poly1.Point(p1) ); }
70  }
71  //2)
72  for (unsigned int p2=0; p2 < poly2.Size(); p2++){
73  if ( poly1.PointInside( poly2.Point(p2) ) ) { IntersectionPoints.push_back( poly2.Point(p2) ); }
74  }
75  //3)
76  //FIND SEGMENT INTERSECTIONS
77  for (unsigned int i=0; i < poly1.Size(); i++){
78  for (unsigned int j=0; j < poly2.Size(); j++){
79  if (SegmentOverlap( poly1.Point(i).first, poly1.Point(i).second,
80  poly1.Point(i+1).first, poly1.Point(i+1).second,
81  poly2.Point(j).first, poly2.Point(j).second,
82  poly2.Point(j+1).first, poly2.Point(j+1).second) )
83  //segments overlap...add intersection to list
84  IntersectionPoints.push_back( GetIntersection( poly1.Point(i).first, poly1.Point(i).second,
85  poly1.Point(i+1).first, poly1.Point(i+1).second,
86  poly2.Point(j).first, poly2.Point(j).second,
87  poly2.Point(j+1).first, poly2.Point(j+1).second) );
88  }//for all segments in poly2
89  }//for all segments in poly1
90 
91  vertices = IntersectionPoints;
92  return;
93 }
const std::pair< float, float > & Point(unsigned int p) const
Definition: Polygon2D.cxx:135
unsigned int Size() const
Create Intersection Polygon.
Definition: Polygon2D.h:47
std::vector< std::pair< float, float > > vertices
Definition: Polygon2D.h:40
std::pair< float, float > GetIntersection(double Ax, double Ay, double Bx, double By, double Cx, double Cy, double Dx, double Dy)
Definition: Polygon2D.cxx:28
bool SegmentOverlap(double Ax, double Ay, double Bx, double By, double Cx, double Cy, double Dx, double Dy)
Definition: Polygon2D.cxx:18
bool PointInside(const std::pair< float, float > &point) const
Definition: Polygon2D.cxx:249
bool PolyOverlap(const Polygon2D &poly2) const
Definition: Polygon2D.cxx:199

Member Function Documentation

float Polygon2D::Area ( ) const

Definition at line 96 of file Polygon2D.cxx.

References vertices.

Referenced by cmtool::CFAlgoVolumeOverlap::Float(), cmtool::CFAlgoWireOverlap::Float(), and Size().

97 {
98  //how? here:
99  //http://www.mathsisfun.com/geometry/area-irregular-polygons.html
100  float area = 0;
101  for (unsigned int i=0; i<vertices.size(); i++){
102  if ( i < (vertices.size()-1) )
103  area += (((vertices.at(i)).second)+((vertices.at(i+1)).second))*(((vertices.at(i)).first)-((vertices.at(i+1)).first))*0.5;
104  if ( i == (vertices.size()-1) )
105  area += (((vertices.at(i)).second)+((vertices.at(0)).second))*(((vertices.at(i)).first)-((vertices.at(0)).first))*0.5;
106  }
107  if (area<0.0)
108  area = -area;
109  return area;
110 }
std::vector< std::pair< float, float > > vertices
Definition: Polygon2D.h:40
bool Polygon2D::Contained ( const Polygon2D poly2) const

Definition at line 271 of file Polygon2D.cxx.

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

Referenced by cmtool::CFAlgoVolumeOverlap::Float(), cmtool::CFAlgoWireOverlap::Float(), PolyOverlapSegments(), and Size().

272 {
273 
274  //loop over poly2 checking wehther
275  //points of poly2 all inside poly1
276  for (unsigned int i=0; i<poly2.Size(); i++){
277  if ( !(this->PointInside( poly2.Point(i)) ) )
278  return false;
279  }
280 
281  return true;
282 
283 }
const std::pair< float, float > & Point(unsigned int p) const
Definition: Polygon2D.cxx:135
unsigned int Size() const
Create Intersection Polygon.
Definition: Polygon2D.h:47
bool PointInside(const std::pair< float, float > &point) const
Definition: Polygon2D.cxx:249
bool Polygon2D::Overlap ( float  slope,
const Polygon2D poly2,
const std::pair< float, float > &  origin 
) const

Definition at line 180 of file Polygon2D.cxx.

References Project().

Referenced by PolyOverlap(), and Size().

183 {
184  //translate and rotate both polygons
185  float theta = tan(slope);
186  //here we translate origin, rotate and find x-coordinates and find range of projection on edge line
187  std::pair<float,float> range1 = this->Project(origin,theta);
188  std::pair<float,float> range2 = poly2.Project(origin,theta);
189  //std::cout << "range 1: " << range1.first << " " << range1.second << std::endl;
190  //std::cout << "range 2: " << range2.first << " " << range2.second << std::endl;
191  //if the two projections don't overlap --> no overlap!
192  if ( ( ((range1.first <= range2.second) and ( range1.first >= range2.first )) or ((range1.second <= range2.second) and ( range1.second >= range2.first )) ) or ( ((range2.first <= range1.second) and ( range2.first >= range1.first )) or ((range2.second <= range1.second) and ( range2.second >= range1.first )) ) )
193  return true; //yes...they overlap
194  else
195  return false; //no....they do not overlap
196 }
std::pair< float, float > Project(const std::pair< float, float > &, float) const
Definition: Polygon2D.cxx:153
constexpr Point origin()
Returns a origin position with a point of the specified type.
Definition: geo_vectors.h:230
float Polygon2D::Perimeter ( ) const

Definition at line 113 of file Polygon2D.cxx.

References vertices.

Referenced by Size().

114 {
115 
116  float perimeter = 0.;
117 
118  for (unsigned int i=0; i<vertices.size(); i++){
119  if ( i < (vertices.size()-1) )
120  perimeter += ( (vertices.at(i).second-vertices.at(i+1).second)*
121  (vertices.at(i).second-vertices.at(i+1).second) +
122  (vertices.at(i).first-vertices.at(i+1).first)*
123  (vertices.at(i).first-vertices.at(i+1).first) );
124  if ( i == (vertices.size()-1) )
125  perimeter += ( (vertices.at(i).second-vertices.at(0).second)*
126  (vertices.at(i).second-vertices.at(0).second) +
127  (vertices.at(i).first-vertices.at(0).first)*
128  (vertices.at(i).first-vertices.at(0).first) );
129  }
130 
131  return sqrt(perimeter);
132 }
std::vector< std::pair< float, float > > vertices
Definition: Polygon2D.h:40
const std::pair< float, float > & Polygon2D::Point ( unsigned int  p) const

Definition at line 135 of file Polygon2D.cxx.

References vertices.

Referenced by Contained(), cmtool::CFAlgoWireOverlap::Float(), cmtool::CFAlgoVolumeOverlap::Float(), PointInside(), Polygon2D(), PolyOverlap(), PolyOverlapSegments(), and Size().

136 {
137  //This function returns the vertex under consideration
138  //as a std::pair<float,float> Returns vertex for argument
139  //from 0 to N-1. For input N = number of sides then
140  //the first vertex is returned
141  if (p<vertices.size())
142  return vertices.at(p);
143  else if (p==vertices.size())
144  return vertices.at(0);
145  else{
146  std::cout << "Out of bounds of Polygon!" <<std::endl;
147  return vertices.at(0);
148  }
149 
150 }
std::vector< std::pair< float, float > > vertices
Definition: Polygon2D.h:40
bool Polygon2D::PointInside ( const std::pair< float, float > &  point) const

Definition at line 249 of file Polygon2D.cxx.

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

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

250 {
251 
252  //any ray originating at point will cross polygon
253  //even number of times if point outside
254  //odd number of times if point inside
255  int intersections = 0;
256  for (unsigned int i=0; i<this->Size(); i++){
257  if ( SegmentOverlap( this->Point(i).first, this->Point(i).second,
258  this->Point(i+1).first, this->Point(i+1).second,
259  10000.0, 10000.0,
260  point.first, point.second) )
261  intersections += 1;
262  }
263  if ( (intersections%2) == 0 )
264  return false;
265  else
266  return true;
267 
268 }
const std::pair< float, float > & Point(unsigned int p) const
Definition: Polygon2D.cxx:135
unsigned int Size() const
Create Intersection Polygon.
Definition: Polygon2D.h:47
bool SegmentOverlap(double Ax, double Ay, double Bx, double By, double Cx, double Cy, double Dx, double Dy)
Definition: Polygon2D.cxx:18
bool Polygon2D::PolyOverlap ( const Polygon2D poly2) const

Definition at line 199 of file Polygon2D.cxx.

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

Referenced by Polygon2D(), and Size().

200 {
201 
202  //start from first pair in vector then check all edges.
203  //edges are (0,1), (1,2), ..., (N,N-1) each pair a pair
204  //of vertexes
205  for (unsigned int i=0; i<this->Size(); i++){//loop over first polygon's vertices
206  //find projection line's slope
207  //line: y=ax+b --- slope is a variable
208  float slope;
209  slope = FindSlope( this->Point(i) , this->Point(i+1) );
210  //if there is even one no-overlap
211  //need to exit and return no overlap!
212  if (! (this->Overlap( slope, poly2, this->Point(i) )) )
213  return false;
214  }//loop over first polygon vertices
215 
216  //do the exact same thing but reversing polygon role
217  for (unsigned int i=0; i<poly2.Size(); i++){//loop over first polygon
218  float slope;
219  slope = FindSlope( poly2.Point(i) , poly2.Point(i+1) );
220  if (!(poly2.Overlap( slope, *this, poly2.Point(i) )) )
221  return false;
222  }//loop over second polygon vertices
223  return true;
224 }
const std::pair< float, float > & Point(unsigned int p) const
Definition: Polygon2D.cxx:135
unsigned int Size() const
Create Intersection Polygon.
Definition: Polygon2D.h:47
bool Overlap(float slope, const Polygon2D &poly2, const std::pair< float, float > &origin) const
Definition: Polygon2D.cxx:180
float FindSlope(const std::pair< float, float > &p1, const std::pair< float, float > &p2)
Definition: Polygon2D.cxx:4
bool Polygon2D::PolyOverlapSegments ( const Polygon2D poly2) const

Definition at line 227 of file Polygon2D.cxx.

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

Referenced by Size().

228 {
229  //if contained in one another then they also overlap:
230  if ( (this->Contained(poly2)) or (poly2.Contained(*this)) ){
231  return true;
232  }
233  //loop over the two polygons checking wehther
234  //two segments ever intersect
235  for (unsigned int i=0; i<this->Size(); i++){
236  for (unsigned int j=0; j<poly2.Size(); j++){
237  if (SegmentOverlap( this->Point(i).first, this->Point(i).second,
238  this->Point(i+1).first, this->Point(i+1).second,
239  poly2.Point(j).first, poly2.Point(j).second,
240  poly2.Point(j+1).first, poly2.Point(j+1).second) ){
241  return true;
242  }
243  }
244  }
245  return false;
246 }
bool Contained(const Polygon2D &poly2) const
Definition: Polygon2D.cxx:271
const std::pair< float, float > & Point(unsigned int p) const
Definition: Polygon2D.cxx:135
unsigned int Size() const
Create Intersection Polygon.
Definition: Polygon2D.h:47
bool SegmentOverlap(double Ax, double Ay, double Bx, double By, double Cx, double Cy, double Dx, double Dy)
Definition: Polygon2D.cxx:18
std::pair< float, float > Polygon2D::Project ( const std::pair< float, float > &  p,
float  theta 
) const

Definition at line 153 of file Polygon2D.cxx.

References vertices.

Referenced by Overlap(), and Size().

155 {
156 
157  std::pair<float,float> range(10000,0);
158  std::pair<float,float> ptmp;
159 
160  for (unsigned int i=0; i<vertices.size(); i++){
161  //Translation
162  //translating each vertex so that origin is on first vertex on polygon's edge being considered
163  ptmp = std::make_pair( (vertices.at(i)).first - p.first , (vertices.at(i)).second - p.second );
164  //Rotation
165  //instead of rotating each (x,y) edge (slow) just find nex x-position which gives us information
166  //on the projection of that vertex on the line we are considering
167  // +x direction is from vertex in consideration (vertex 'i' in loop) to next vertex
168  //now find the x-coordinate of that vertex after it is rotated such that edge is now + x axis
169  float xnew = (ptmp.first)*cos(theta) + (ptmp.second)*sin(theta);
170  //finally calculate range of projection on x-axis: look at every x position and compare it to range
171  if ( xnew < range.first )
172  range.first = xnew;
173  if ( xnew > range.second )
174  range.second = xnew;
175  }
176  return range;
177 }
std::vector< std::pair< float, float > > vertices
Definition: Polygon2D.h:40
unsigned int Polygon2D::Size ( ) const
inline
void Polygon2D::UntanglePolygon ( )

check if poly2 is inside poly1

Definition at line 286 of file Polygon2D.cxx.

References SegmentOverlap(), tmp, and vertices.

Referenced by cmtool::CFAlgoVolumeOverlap::Float(), cmtool::CFAlgoWireOverlap::Float(), and Size().

287 {
288 
289  //loop over edges
290  for ( unsigned int i=0; i < vertices.size()-1; i++){
291  double Ax = vertices.at(i).first;
292  double Ay = vertices.at(i).second;
293  double Bx = vertices.at(i+1).first;
294  double By = vertices.at(i+1).second;
295  //loop over edges that have not been checked yet
296  for (unsigned int j=i+2; j < vertices.size()-1; j++){
297  //avoid consecutive segments
298  if ( vertices.at(i) == vertices.at(j+1) )
299  continue;
300  else{
301  double Cx = vertices.at(j).first;
302  double Cy = vertices.at(j).second;
303  double Dx = vertices.at(j+1).first;
304  double Dy = vertices.at(j+1).second;
305 
306  if ( SegmentOverlap( Ax, Ay, Bx, By, Cx, Cy, Dx, Dy ) ){
307  std::pair<float, float> tmp = vertices.at(i+1);
308  vertices.at(i+1) = vertices.at(j);
309  vertices.at(j) = tmp;
310  //swapped polygon, now do recursion to make sure
311  this->UntanglePolygon();
312  }//if crossing
313  }
314  }//second loop
315  }//first loop
316 
317 }
Float_t tmp
Definition: plot.C:37
std::vector< std::pair< float, float > > vertices
Definition: Polygon2D.h:40
bool SegmentOverlap(double Ax, double Ay, double Bx, double By, double Cx, double Cy, double Dx, double Dy)
Definition: Polygon2D.cxx:18
void UntanglePolygon()
check if poly2 is inside poly1
Definition: Polygon2D.cxx:286

Member Data Documentation

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

Definition at line 40 of file Polygon2D.h.

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


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