예제 #1
0
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;
    }
}
예제 #2
0
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();
}
예제 #3
0
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;
}
예제 #4
0
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();
}
예제 #5
0
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() ) );
}
예제 #6
0
파일: minkowski.cpp 프로젝트: CGAL/releases
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());
      }
    }
  }
}
예제 #7
0
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;
}