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; }
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(); }
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 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; }