bool Polygon2::containsAllOf(const Polygon2 &polygon) const { // If any vertex of @polygon is outside the boundary of @this, then // @polygon is not wholly inside @this for (int polyI = 0; polyI < polygon.size(); polyI++) { if ( !contains( polygon[polyI] ) ) { return false; } } // If any edge of @polygon intersects @this, then // @polygon is not wholly contained within @this int edgeIPrev = polygon.size() - 1; for (int edgeI = 0; edgeI < polygon.size(); edgeI++) { Segment2 edge( polygon[edgeIPrev], polygon[edgeI] ); if ( checkEdgeIntersection( edge ) ) { return false; } edgeIPrev = edgeI; } return true; }
bool Polygon2::containsPartOf(const Polygon2 &polygon) const { // If any vertex of @polygon is inside the boundary of @this, then // @polygon is partially inside @this for (int polyI = 0; polyI < polygon.size(); polyI++) { if ( contains( polygon[polyI] ) ) { return true; } } // If any vertex of @this is inside the boundary of @polygon, then // @polygon is partially inside @this for (int vertexI = 0; vertexI < vertices.size(); vertexI++) { if ( polygon.contains( vertices[vertexI] ) ) { return true; } } // If any edge of @polygon intersects @this, then // @polygon is partially inside @this int edgeIPrev = polygon.size() - 1; for (int edgeI = 0; edgeI < polygon.size(); edgeI++) { Segment2 edge( polygon[edgeIPrev], polygon[edgeI] ); if ( checkEdgeIntersection( edge ) ) { return true; } edgeIPrev = edgeI; } // No intersection at all return false; }
void CreateTranslatorForPolygon( const Polygon2& poly, CoordTranslator2& trans) { if (poly.empty()) return; trans.mSrcMin = poly[0]; trans.mSrcMax = poly[0]; for (int n = 1; n < poly.size(); ++n) { trans.mSrcMin.x_ = min(trans.mSrcMin.x(), poly[n].x()); trans.mSrcMin.y_ = min(trans.mSrcMin.y(), poly[n].y()); trans.mSrcMax.x_ = max(trans.mSrcMax.x(), poly[n].x()); trans.mSrcMax.y_ = max(trans.mSrcMax.y(), poly[n].y()); } trans.mDstMin.x_ = 0.0; trans.mDstMax.y_ = 0.0; trans.mDstMax.x_ = (trans.mSrcMax.x() - trans.mSrcMin.x()) * DEG_TO_MTR_LAT * cos((trans.mSrcMin.y() + trans.mSrcMax.y()) * 0.5 * DEG_TO_RAD); trans.mDstMax.y_ = (trans.mSrcMax.y() - trans.mSrcMin.y()) * DEG_TO_MTR_LAT; }
bool build_convex_polygon( Pmwx::Ccb_halfedge_circulator ccb, vector<pair<Pmwx::Halfedge_handle, Pmwx::Halfedge_handle> >& sides, const CoordTranslator2& trans, Polygon2& metric_bounds, double max_err_mtrs, double min_side_len) { double e_sq = max_err_mtrs*max_err_mtrs; sides.clear(); metric_bounds.clear(); Pmwx::Ccb_halfedge_circulator circ(ccb); // Bbox2 bounds; // // do { // bounds += cgal2ben(circ->source()->point()); // } while (++circ != ccb); Pmwx::Ccb_halfedge_circulator start,next; start = ccb; do { --start; if(!sides_can_merge(start,ccb)) break; if(!within_err_metric(start,ccb,trans,e_sq)) break; } while(start != ccb); ++start; // now we can go around. circ = start; //int ne = count_circulator(start); //printf("Poly has %d sides.\n", ne); do { Pmwx::Ccb_halfedge_circulator stop(circ); do { ++stop; } while(sides_can_merge(circ,stop) && within_err_metric(circ,stop,trans,e_sq) && stop != start); --stop; //printf("Pushing side of %d, %d\n", circulator_distance_to(start, circ),circulator_distance_to(start,stop)); sides.push_back(pair<Pmwx::Halfedge_handle,Pmwx::Halfedge_handle>(circ, stop)); ++stop; circ = stop; } while(circ != start); if(sides.size() < 3) { //debug_mesh_point(bounds.centroid(),1,1,1); return false; } int i, j, k; vector<Segment2> msides; for(i = 0; i < sides.size(); ++i) { j = (i + 1) % sides.size(); DebugAssert(sides[i].second->target() == sides[j].first->source()); msides.push_back(Segment2( trans.Forward(cgal2ben(sides[i].first->source()->point())), trans.Forward(cgal2ben(sides[i].second->target()->point())))); } vector<Segment2> debug(msides); for(i = 0; i < sides.size(); ++i) { j = (i + 1) % sides.size(); Vector2 v1(msides[i].p1,msides[i].p2); Vector2 v2(msides[j].p1,msides[j].p2); v1.normalize(); v2.normalize(); if(v1.dot(v2) > 0.9998 || !v1.left_turn(v2)) { //debug_mesh_point(trans.Reverse(msides[i].p2),1,0,0); return false; } double w = width_for_he(sides[i].first); if(w) { v1 = v1.perpendicular_ccw(); v1 *= w; msides[i].p1 += v1; msides[i].p2 += v1; } } for(j = 0; j < sides.size(); ++j) { i = (j + sides.size() - 1) % sides.size(); Line2 li(msides[i]), lj(msides[j]); Point2 p; if(!li.intersect(lj,p)) { Assert(!"Failure to intersect.\n"); return false; } metric_bounds.push_back(p); } for(i = 0; i < metric_bounds.size(); ++i) { j = (i + 1) % metric_bounds.size(); k = (i + 2) % metric_bounds.size(); if(metric_bounds.side(i).squared_length() < (min_side_len*min_side_len)) { //debug_mesh_line(trans.Reverse(metric_bounds.side(i).p1),trans.Reverse(metric_bounds.side(i).p2),1,1,0,1,1,0); return false; } if(!left_turn(metric_bounds[i],metric_bounds[j],metric_bounds[k])) { //debug_mesh_point(trans.Reverse(metric_bounds[j]),1,1,0); return false; } if(Vector2(msides[i].p1,msides[i].p2).dot(Vector2(metric_bounds[i],metric_bounds[j])) < 0.0) { //debug_mesh_line(trans.Reverse(msides[i].p1),trans.Reverse(msides[i].p2),1,0,0,1,0,0); return false; } } DebugAssert(metric_bounds.size() == msides.size()); DebugAssert(msides.size() == sides.size()); return true; }