double GDALGeometricAttributes::percentageFilled(OGRPolygon * ogr_poly) { char* geo; ogr_poly->exportToWkt(&geo); std::auto_ptr< SFCGAL::Geometry > g( SFCGAL::io::readWkt(geo)); SFCGAL::Polygon poly = g->as<SFCGAL::Polygon>(); if (!poly.toPolygon_2(false).is_simple()) { DM::Logger(DM::Warning) << "Polygon is not simple"; return -1; } //Transfer to GDAL polygon Polygon_with_holes_2 p = poly.toPolygon_with_holes_2(true); Polygon_2 p_c; CGAL::convex_hull_2(p.outer_boundary().vertices_begin(), p.outer_boundary().vertices_end(), std::back_inserter(p_c)); //Cacluate Minimal Rect Polygon_2 p_m; CGAL::min_rectangle_2(p_c.vertices_begin(), p_c.vertices_end(), std::back_inserter(p_m)); return ogr_poly->get_Area() / CGAL::to_double(p_m.area()); }
void GDALParceling::splitePoly(Polygon_with_holes_2 &p) { //Convex Hull (GDAL algorithm doesn't work without) Polygon_2 p_c; CGAL::convex_hull_2(p.outer_boundary().vertices_begin(), p.outer_boundary().vertices_end(), std::back_inserter(p_c)); //Cacluate Minimal Rect Polygon_2 p_m; CGAL::min_rectangle_2(p_c.vertices_begin(), p_c.vertices_end(), std::back_inserter(p_m)); Pwh_list_2 splitters(this->splitter(p_m)); if (splitters.size() == 0) { SFCGAL::Polygon split_geo(p); addToSystem(split_geo); return; } foreach (Polygon_with_holes_2 pwh, splitters) { Pwh_list_2 split_ress; CGAL::intersection(p, pwh, std::back_inserter(split_ress)); foreach(Polygon_with_holes_2 pwh_split, split_ress) { if (!pwh_split.outer_boundary().is_simple()) { DM::Logger(DM::Error) << "NOT SIMPLE"; } splitePoly(pwh_split); } }
int main () { // Construct the first polygon (a triangle). Polygon_2 P; P.push_back (Point_2 (0, 0)); P.push_back (Point_2 (6, 0)); P.push_back (Point_2 (3, 5)); // Construct the second polygon (a triangle). Polygon_2 Q; Q.push_back (Point_2 (0, 0)); Q.push_back (Point_2 (2, -2)); Q.push_back (Point_2 (2, 2)); // Compute the Minkowski sum. Polygon_with_holes_2 sum = minkowski_sum_2 (P, Q); CGAL_assertion (sum.number_of_holes() == 0); std::cout << "P = "; print_polygon (P); std::cout << "Q = "; print_polygon (Q); std::cout << "P (+) Q = "; print_polygon (sum.outer_boundary()); return (0); }
std::list<Polygon_with_holes_2> CstmCGAL::splitPoly(const Polygon_with_holes_2& poly) { std::vector<Point_2> outerBoundary = std::vector<Point_2>( poly.outer_boundary().vertices_begin(),poly.outer_boundary().vertices_end()); std::list<Polygon_with_holes_2> result; for (unsigned int i = 0 ; i < outerBoundary.size() ; i++) { for (unsigned int j = i+1 ; j < outerBoundary.size() ; j++) { if (outerBoundary[i] == outerBoundary[j]) { result.splice(result.end(), splitPoly(Polygon_with_holes_2( Polygon_2(outerBoundary.begin() + i, outerBoundary.begin() + j) ))); for (unsigned int k = i+1 ; k < outerBoundary.size() ; k++) { outerBoundary[k] = outerBoundary[k + j - i]; } outerBoundary.resize(outerBoundary.size() - j + i); break; } } } result.push_back(Polygon_with_holes_2( Polygon_2(outerBoundary.begin(), outerBoundary.end()))); return result; }
void gnuplot_print_polygon(std::ostream& out, const Polygon_with_holes_2& P) { gnuplot_print_polygon(out, P.outer_boundary()); out << std::endl << std::endl << std::endl; for (Polygon_with_holes_2::Hole_const_iterator it = P.holes_begin(); it != P.holes_end(); ++it) { gnuplot_print_polygon(out, *it); out << std::endl << std::endl << std::endl; } }
std::string pp(const Polygon_with_holes_2& pwh) { std::stringstream out; out << "[Outer boundary: " << pp(pwh.outer_boundary()) << "] "; for (Polygon_with_holes_2::Hole_const_iterator it = pwh.holes_begin(); it != pwh.holes_end(); ++it) { out << "Hole: " << pp(*it) << " "; } return out.str(); }
void perturb(Polygon_with_holes_2& p, Number_type epsilon) { perturb(p.outer_boundary(), epsilon); // Polygon_with_holes_2 q(p.outer_boundary()); for (Polygon_with_holes_2::Hole_iterator it = p.holes_begin(); it != p.holes_end(); ++it) { perturb(*it, epsilon); // q.add_hole(); } // p = q; }
double GDALGeometricAttributes::aspectRationBB(OGRPolygon * ogr_poly) { char* geo; ogr_poly->exportToWkt(&geo); std::auto_ptr< SFCGAL::Geometry > g( SFCGAL::io::readWkt(geo)); SFCGAL::Polygon poly = g->as<SFCGAL::Polygon>(); if (!poly.toPolygon_2(false).is_simple()) { DM::Logger(DM::Warning) << "Polygon is not simple"; return -1; } //Transfer to GDAL polygon Polygon_with_holes_2 p = poly.toPolygon_with_holes_2(true); Polygon_2 p_c; CGAL::convex_hull_2(p.outer_boundary().vertices_begin(), p.outer_boundary().vertices_end(), std::back_inserter(p_c)); //Cacluate Minimal Rect Polygon_2 p_m; CGAL::min_rectangle_2(p_c.vertices_begin(), p_c.vertices_end(), std::back_inserter(p_m)); Point_2 p1 = p_m.vertex(0); Point_2 p2 = p_m.vertex(1); Point_2 p3 = p_m.vertex(2); Point_2 p4 = p_m.vertex(3); Vector_2 v1 = (p2-p1); Vector_2 v2 = (p3-p2); double l1 = sqrt(CGAL::to_double(v1.squared_length())); double l2 = sqrt(CGAL::to_double(v2.squared_length())); double aspect_ration = l1/l2; if (aspect_ration < 1.0) { aspect_ration = 1.0/aspect_ration; } return aspect_ration; }
Polygon_2 CPElement::intersection_with_support(const Polygon_2& P) const { static log4cplus::Logger logger = Logger("intersection_with_support"); typedef std::list<Bso_polygon_with_holes_2> Pwh_list_2; Pwh_list_2 intR; Pwh_list_2::const_iterator it; CGAL::intersection(change_kernel<Bso_kernel>(P), change_kernel<Bso_kernel>(support()), std::back_inserter(intR)); if (intR.size() > 1) { LOG4CPLUS_WARN(logger, "intersection yielded more than one component"); } Polygon_with_holes_2 pwh = to_common(*intR.begin()); if (pwh.holes_begin() != pwh.holes_end()) { LOG4CPLUS_WARN(logger, "intersection yielded holes"); } return pwh.outer_boundary(); }
void ParcelSplitWorker::splitePoly(Polygon_with_holes_2 &p) { //Convex Hull (GDAL algorithm doesn't work without) Polygon_2 p_c; CGAL::convex_hull_2(p.outer_boundary().vertices_begin(), p.outer_boundary().vertices_end(), std::back_inserter(p_c)); //Cacluate Minimal Rect Polygon_2 p_m; CGAL::min_rectangle_2(p_c.vertices_begin(), p_c.vertices_end(), std::back_inserter(p_m)); Pwh_list_2 splitters(this->splitter(p_m)); foreach (Polygon_with_holes_2 pwh, splitters) { Pwh_list_2 split_ress; CGAL::intersection(p, pwh, std::back_inserter(split_ress)); foreach(Polygon_with_holes_2 pwh_split, split_ress) { SFCGAL::Polygon split_geo(pwh_split); QString wkt = QString(split_geo.asText(16).c_str()); module->addToSystem(wkt); //emit resultPolygon(wkt); }
std::auto_ptr< Geometry > building( const Polygon& g, const Kernel::FT& wallHeight, const Kernel::FT& roofSlope ) { //typedef Straight_skeleton_2::Vertex_const_handle Vertex_const_handle ; typedef Straight_skeleton_2::Halfedge_const_handle Halfedge_const_handle ; //typedef Straight_skeleton_2::Halfedge_const_iterator Halfedge_const_iterator ; typedef Straight_skeleton_2::Face_const_iterator Face_const_iterator ; // convert to CGAL polygon and generate straight skeleton Polygon_with_holes_2 polygon = g.toPolygon_with_holes_2() ; // fix orientation algorithm::makeValidOrientation( polygon ) ; boost::shared_ptr< Straight_skeleton_2 > skeleton = CGAL::create_interior_straight_skeleton_2( polygon ) ; std::auto_ptr< PolyhedralSurface > shell( new PolyhedralSurface ); // bottom part { Polygon bottom( polygon ); bottom.reverse(); algorithm::force3D( bottom ); shell->addPolygon( bottom ); } // walls { //exterior rings _buildingWall( polygon.outer_boundary(), wallHeight, *shell ) ; //interior rings for ( Polygon_with_holes_2::Hole_const_iterator it = polygon.holes_begin(); it != polygon.holes_end(); ++it ) { _buildingWall( *it, wallHeight, *shell ) ; } } // roof { for ( Face_const_iterator it = skeleton->faces_begin(); it != skeleton->faces_end(); ++it ) { LineString roofFaceRing ; Halfedge_const_handle h = it->halfedge(), done( h ) ; bool infiniteTimeFound = false ; do { infiniteTimeFound = infiniteTimeFound || h->has_infinite_time() ; Point_2 point = h->vertex()->point() ; Kernel::FT zPoint = wallHeight + h->vertex()->time() * roofSlope ; roofFaceRing.addPoint( Point( point.x(), point.y(), zPoint ) ); h = h->next() ; } while ( h != done && ! infiniteTimeFound ); if ( ! infiniteTimeFound ) { roofFaceRing.addPoint( roofFaceRing.startPoint() ); shell->addPolygon( Polygon( roofFaceRing ) ); } } } return std::auto_ptr< Geometry >( new Solid( shell.release() ) ); }
void MapDrawFunction(AG_Event *event) { GLdouble vz = -2.0; GLfloat ambient[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; GLfloat diffuse[4] = { 1.f, 1.0f, 1.0f, 1.0f }; GLfloat specular[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; int wireframe = 0; enum { FLATSHADING, SMOOTHSHADING } shading = FLATSHADING; int i; GLfloat pos[4]; glLoadIdentity(); glPushAttrib(GL_POLYGON_BIT|GL_LIGHTING_BIT|GL_DEPTH_BUFFER_BIT); glEnable(GL_POINT_SMOOTH); glEnable(GL_DEPTH_TEST); //glEnable(GL_LIGHTING); //glEnable(GL_LIGHT0); // Create light components //GLfloat ambientLight[] = { 0.2f, 0.2f, 0.2f, 0.1f }; GLfloat diffuseLight[] = { 1, 1, 1, 1.0f }; GLfloat specularLight[] = { 0.5f, 0.5f, 0.5f, 1.0f }; GLfloat position[] = { cursorwX, cursorwY, 0.5f, 1.0f }; // Assign created components to GL_LIGHT0 //glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight); glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight); glLightfv(GL_LIGHT0, GL_POSITION, position); glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.0f); glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.002f); glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.0f); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE); glClearColor(0.0f,0.0f,0.0f,1.0f); glPushMatrix(); glTranslated(0.0, 0.0, vz); GLfloat visi[4]={1.0,0.0,0.0,1.0}; glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, visi); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, visi); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, visi); glColor3f(0.9,0.9,0.6); mapdraw(); for (int i=0;i<sceneVertices.size();i++){ glBegin(GL_LINE_LOOP); for (int j=0;j<sceneVertices[i].size();j++){ glVertex3f( sceneVertices[i][j][0], sceneVertices[i][j][1], 0.0f); }; glEnd(); }; glColor3f(0.9,0.9,0.0); for (int i=0;i<mapEnvCollision.h()+1;i++){ glBegin(GL_LINE_LOOP); for (int j=0;j<mapEnvCollision[i].n();j++){ glVertex3f( mapEnvCollision[i][j].x(), mapEnvCollision[i][j].y(), 0.0f); }; //glVertex3f( sceneVertices[i][0].x(), sceneVertices[i][0].y(), 0.0f); glEnd(); }; gluTessBeginPolygon (tess, NULL); gluTessBeginContour (tess); GLdouble data[visiBounded.outer_boundary().size()][3]; CGAL::Polygon_2<Kernel>::Vertex_iterator vit; i=0; for (vit=visiBounded.outer_boundary().vertices_begin();vit!=visiBounded.outer_boundary().vertices_end();++vit) { data[i][0]=vit->x(); data[i][1]=vit->y(); data[i][2]=0; gluTessVertex (tess, data[i], data[i]); i++; } /* for (i=0; i<visiPoly.n();i++) { data[i][0]=visiPoly[i].x(); data[i][1]=visiPoly[i].y(); data[i][2]=0; gluTessVertex (tess, data[i], data[i]); } */ gluTessEndContour (tess); gluEndPolygon (tess); glBegin(GL_LINE_LOOP); for (int i=0;i<visiPoly.n();i++){ glVertex3f(visiPoly[i].x(),visiPoly[i].y(),0.0f); } glEnd(); glColor3f(1.0,0.0,0.0); glBegin(GL_LINE_STRIP); for (int i=0;i<motionPath.size();i++){ glVertex3f(motionPath[i].x(),motionPath[i].y(),0.1f); } glEnd(); //glPopMatrix(); GLfloat marker[4]={1.0,0.0,0.0,1.0}; //glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, marker); glColor3f(1.0,0.0,0.0); guest1.Draw(); glGetDoublev(GL_MODELVIEW_MATRIX,modelview); glGetDoublev(GL_PROJECTION_MATRIX,projection); glGetIntegerv(GL_VIEWPORT,viewport) ; glColor3f(1.0,1.0,1.0); glBegin(GL_TRIANGLES); glVertex3f(cursorwX,cursorwY+1/sqrt(2)*10,1.0f); glVertex3f(cursorwX-1/sqrt(2)*10,cursorwY-1/sqrt(2)*10,1.0f); glVertex3f(cursorwX+1/sqrt(2)*10,cursorwY-1/sqrt(2)*10,1.0f); glEnd(); glPopMatrix(); glPopAttrib(); };
void SubSelectIpelet::protected_run(int fn) { if (fn==2) { show_help(); return; } std::list<Circle_2> cir_list; std::list<Polygon_2> pol_list; Iso_rectangle_2 bbox= read_active_objects( CGAL::dispatch_or_drop_output<Polygon_2,Circle_2>( std::back_inserter(pol_list), std::back_inserter(cir_list) ) ); if (fn==0 && pol_list.size()!=2){ print_error_message("You must select exactly two polygons"); return; } std::list<double> r_offsets; for (std::list<Circle_2>::iterator it=cir_list.begin();it!=cir_list.end();++it) r_offsets.push_back(sqrt(CGAL::to_double(it->squared_radius()))); IpeMatrix tfm (1,0,0,1,-CGAL::to_double(bbox.min().x()),-CGAL::to_double(bbox.min().y())); for (std::list<Polygon_2>::iterator it=pol_list.begin();it!=pol_list.end();++it) if(!it->is_simple()){ print_error_message("Polygon(s) must be simple"); } if (fn==0){ Polygon_2 polygon1=*pol_list.begin(); Polygon_2 polygon2=*++pol_list.begin(); Polygon_with_holes_2 sum = minkowski_sum_2 (polygon1, polygon2); std::list<Point_2> LP; for (Polygon_2::iterator it=sum.outer_boundary().vertices_begin();it!= sum.outer_boundary().vertices_end();++it) LP.push_back(*it); draw_polyline_in_ipe(LP.begin(),LP.end(),true,false,false); for (Polygon_with_holes_2::Hole_const_iterator poly_it = sum.holes_begin(); poly_it != sum.holes_end(); ++poly_it){ LP.clear(); for (Polygon_2::iterator it=poly_it->vertices_begin();it!= poly_it->vertices_end();++it) LP.push_back(*it); draw_polyline_in_ipe(LP.begin(),LP.end(),true,false,false); } create_polygon_with_holes(true); transform_selected_objects_(tfm); } else{ if (r_offsets.size()==0) r_offsets.push_back(10); for (std::list<Polygon_2>::iterator it_pol=pol_list.begin();it_pol!=pol_list.end();++it_pol){ for(std::list<double>::iterator it=r_offsets.begin();it!=r_offsets.end();++it){ Offset_polygon_with_holes_2 offset=approximated_offset_2 (*it_pol, *it, 0.0001); std::list<Segment_2> LS; for( Offset_polygon_2::Curve_iterator itt=offset.outer_boundary().curves_begin(); itt!=offset.outer_boundary().curves_end();++itt){ Point_2 S=Point_2(CGAL::to_double(itt->source().x()),CGAL::to_double(itt->source().y())); Point_2 T=Point_2(CGAL::to_double(itt->target().x()),CGAL::to_double(itt->target().y())); if (itt->is_linear ()) LS.push_back(Segment_2(S,T)); if (itt->is_circular()) draw_in_ipe(Circular_arc_2(itt->supporting_circle(),S,T,itt->supporting_circle().orientation())); } draw_in_ipe(LS.begin(),LS.end()); } } } }
PwhPtr CstmCGAL::applyOffset(double offset, const Polygon_with_holes_2& poly) { // This code is inspired from the CGAL example Straight_skeleton_2/Low_level_API // As the offset can only produce an interior polygon, we need to produce a frame // that encloses the polygon and is big enough so that the offset of the contour // does not interfere with the one ot the polygon. See CGAL doc page for more info boost::optional<double> margin = CGAL::compute_outer_frame_margin( poly.outer_boundary().vertices_begin(),poly.outer_boundary().vertices_end(),offset); if ( margin ) { CGAL::Bbox_2 bbox = CGAL::bbox_2(poly.outer_boundary().vertices_begin(),poly.outer_boundary().vertices_end()); double fxmin = bbox.xmin() - *margin ; double fxmax = bbox.xmax() + *margin ; double fymin = bbox.ymin() - *margin ; double fymax = bbox.ymax() + *margin ; // Create the rectangular frame Point_2 frame[4]= { Point_2(fxmin,fymin) , Point_2(fxmax,fymin) , Point_2(fxmax,fymax) , Point_2(fxmin,fymax) } ; SsBuilder ssb ; ssb.enter_contour(frame,frame+4); // We have to revert the orientation of the polygon std::vector<Point_2> outerBoundary = std::vector<Point_2>( poly.outer_boundary().vertices_begin(),poly.outer_boundary().vertices_end()); ssb.enter_contour(outerBoundary.rbegin(), outerBoundary.rend()); SsPtr ss = ssb.construct_skeleton(); if ( ss ) { std::vector<Polygon_2Ptr> offset_contours ; OffsetBuilder ob(*ss); ob.construct_offset_contours(offset, std::back_inserter(offset_contours)); // Locate the offset contour that corresponds to the frame // That must be the outmost offset contour, which in turn must be the one // with the largest unsigned area. std::vector<Polygon_2Ptr>::iterator f = offset_contours.end(); double lLargestArea = 0.0 ; for (std::vector<Polygon_2Ptr>::iterator i = offset_contours.begin(); i != offset_contours.end(); ++ i) { double lArea = CGAL_NTS abs( (*i)->area() ) ; //Take abs() as Polygon_2::area() is signed. if ( lArea > lLargestArea ) { f = i ; lLargestArea = lArea ; } } offset_contours.erase(f); // Construct result polygon std::vector<Point_2> newOuterBoundary = std::vector<Point_2>( offset_contours.front()->vertices_begin(), offset_contours.front()->vertices_end()); Polygon_with_holes_2 result = Polygon_with_holes_2(Polygon_2(newOuterBoundary.rbegin(), newOuterBoundary.rend())); // We have to handle the holes separately for (auto it = poly.holes_begin() ; it != poly.holes_end() ; it++) { std::vector<Point_2> hole = std::vector<Point_2>(it->vertices_begin(),it->vertices_end()); std::vector<PwhPtr> holeOffsets = CGAL::create_interior_skeleton_and_offset_polygons_with_holes_2(offset, Polygon_with_holes_2(Polygon_2(hole.begin(), hole.end()))); for (auto it2 = holeOffsets.begin() ; it2 != holeOffsets.end() ; it++) { std::vector<Point_2> revertNewHoles = std::vector<Point_2>( (*it2)->outer_boundary().vertices_begin(),(*it2)->outer_boundary().vertices_end()); result.add_hole(Polygon_2(revertNewHoles.rbegin(), revertNewHoles.rend())); } } return boost::make_shared<Polygon_with_holes_2>(result); } } return NULL; }