Example #1
0
void TreeNode::draw() const
{
  std::ofstream ofs(NODE_FILENAME);
  cairo_t *cr;
  cairo_surface_t *surface;
  CGAL::Bbox_2 bbox = region.bbox();

  assert(bbox.xmin() >= 0.0);
  assert(bbox.ymin() >= 0.0);

#ifdef PDF_OUTPUT
  surface = cairo_pdf_surface_create(IMG_FILENAME, bbox.xmax(), bbox.ymax());
#endif
#ifdef PNG_OUTPUT
  surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, bbox.xmax(), bbox.ymax());
#endif
  cr = cairo_create(surface);

  cairo_select_font_face(cr, "serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
  cairo_set_font_size(cr, 10.0);

  draw_region(cr);
  draw_text(cr);
  write_centroid(ofs);

  cairo_show_page(cr);
  cairo_destroy(cr);
#ifdef PNG_OUTPUT
  cairo_surface_write_to_png(surface, IMG_FILENAME);
#endif
  cairo_surface_destroy(surface);
}
//Constructs the grid based on the polygon's bounding box and generates a random point if inside polygon
Points PathPlanner::getRandGridPoints(){
	//Grid
	CGAL::Bbox_2 box = this->BPpoly.bbox();
	long double xmini = box.xmin();
	long double ymini = box.ymin();
	long double xmaxi = box.xmax();
	long double ymaxi = box.ymax();
	cout<<xmini<<" "<<xmaxi<<" "<<ymini<<" "<<ymaxi<<'\n';
	Point_2 iterator;
	vector<Grid> grids;
	Points randGridPoints;
	for(long double i =ymini; i<ymaxi; i += this->gridSideLen ){
		for(long double j = xmini; j<xmaxi; j+= this->gridSideLen ){
			grids.push_back( Grid( Point_2(j,i) , this->gridSideLen) );
			cout<<"row: "<<i<<" column: "<<j<<'\n';
		}
	}
	for (int i =0 ; i <grids.size();i++){
		if(grids[i].is_bounded(BPpoly)){
			randGridPoints.push_back(grids[i].genRandPoint());
			grids[i].printGrid();
		}
	}
	return randGridPoints;

}
  virtual QRectF boundingRect() const
  {
    return QRectF(_bb.xmin(),
		  _bb.ymin(),
		  _bb.xmax() - _bb.xmin(),
		  _bb.ymax() - _bb.ymin());
  }
Example #4
0
void MyWindow::open_linear_polygon_file()
{

  QString s = QFileDialog::getOpenFileName(file_name,
					   QString::null,
					   this,
					   "open file dialog",
					   "Choose a file" );
  if (s==QString::null)
    return;
  file_name=s;

  std::ifstream in_file(s.ascii());
  if (!in_file.is_open())
    {
      QMessageBox::warning( widget,"Open","Can't open file");
      return ;
    }

  CGAL::Bbox_2 box = CGAL::Bbox_2 (widget->x_min(), widget->y_min(),
				   widget->x_max(), widget->y_max());
  QCursor old = widget->cursor();
  widget->setCursor(Qt::WaitCursor);
  widget->lock();
  widget->clear_history();

  Linear_polygon_2 pgn;
  in_file >> pgn;
  if (pgn.is_empty())
    {
      widget->unlock();
      widget->setCursor(old);
      return;
    }
  if (pgn.orientation() != CGAL::COUNTERCLOCKWISE)
    pgn.reverse_orientation();

  const Polygon_2& circ_pgn = linear_2_circ(pgn);


  if (red_active)
    red_set.join(circ_pgn);
  else
    blue_set.join(circ_pgn);


  box = box + circ_pgn.bbox();
  widget->set_window(box.xmin(),
		     box.xmax(),
		     box.ymin(),
		     box.ymax());
  widget->unlock();
  newtoolbar->reset();
  something_changed();
  widget->setCursor(old);
}
Example #5
0
void MyWindow::open_dxf_file()
{

  QString s = QFileDialog::getOpenFileName(file_name,
					   QString::null,
					   this,
					   "open file dialog",
					   "Choose a file" );
  if (s==QString::null)
    return;
  file_name=s;

  std::ifstream in_file(s.ascii());
  if (!in_file.is_open())
    {
      QMessageBox::warning( widget,"Open","Can't open file");
      return ;
    }
  bool are_simple;
  int answer = 0;
  answer =
    QMessageBox::question(this, QString("Open file"),
			  QString("Are all polygons simple and without holes?"),
			  QString("Yes"), QString("No"), QString::null, 0 , 0);
  if (answer == 0)
    are_simple = true;
  else
    are_simple = false;

  CGAL::Bbox_2 box = CGAL::Bbox_2 (widget->x_min(), widget->y_min(),
				   widget->x_max(), widget->y_max());
  QCursor old = widget->cursor();
  widget->setCursor(Qt::WaitCursor);
  widget->lock();
  widget->clear_history();

  CGAL::Dxf_bsop_reader<Kernel> reader;
  std::vector<Polygon_2>  circ_polygons;
  std::vector<Polygon_with_holes>  circ_polygons_with_holes;
  reader(in_file,
	 std::back_inserter(circ_polygons),
	 std::back_inserter(circ_polygons_with_holes),
	 !are_simple);

  if (red_active)
    {
      red_set.join(circ_polygons.begin(),
		   circ_polygons.end(),
		   circ_polygons_with_holes.begin(),
		   circ_polygons_with_holes.end());
    }
  else
    {
      blue_set.join(circ_polygons.begin(),
		    circ_polygons.end(),
		    circ_polygons_with_holes.begin(),
		    circ_polygons_with_holes.end());
    }

  if (!circ_polygons.empty())
    {
      box = circ_polygons.front().bbox();
    }
  else if (!circ_polygons_with_holes.empty())
    {
      box = circ_polygons_with_holes.front().outer_boundary().bbox();
    }

  std::vector<Polygon_2>::iterator itr1 = circ_polygons.begin();
  for(itr1 = circ_polygons.begin();
      itr1 != circ_polygons.end();
      ++itr1)
    {
      box = box + itr1->bbox();
    }
  std::vector<Polygon_with_holes>::iterator itr2;

  for (itr2 = circ_polygons_with_holes.begin();
       itr2 != circ_polygons_with_holes.end();
       ++itr2)
    {
      box = box + itr2->outer_boundary().bbox();
    }

  widget->set_window(box.xmin(),
		     box.xmax(),
		     box.ymin(),
		     box.ymax());
  widget->unlock();
  newtoolbar->reset();
  something_changed();
  widget->setCursor(old);
}
Example #6
0
int main()
{
  // A start-shaped polygon, oriented counter-clockwise as required for outer contours.
  Point_2 pts[] = { Point_2(-1,-1)
                  , Point_2(0,-12)
                  , Point_2(1,-1)
                  , Point_2(12,0)
                  , Point_2(1,1)
                  , Point_2(0,12)
                  , Point_2(-1,1)
                  , Point_2(-12,0)
                  } ;

  std::vector<Point_2> star(pts,pts+8);

  // We want an offset contour in the outside.
  // Since the package doesn't support that operation directly, we use the following trick:
  // (1) Place the polygon as a hole of a big outer frame.
  // (2) Construct the skeleton on the interior of that frame (with the polygon as a hole)
  // (3) Construc the offset contours
  // (4) Identify the offset contour that corresponds to the frame and remove it from the result


  double offset = 3 ; // The offset distance

  // First we need to determine the proper separation between the polygon and the frame.
  // We use this helper function provided in the package.
  boost::optional<double> margin = CGAL::compute_outer_frame_margin(star.begin(),star.end(),offset);

  // Proceed only if the margin was computed (an extremely sharp corner might cause overflow)
  if ( margin )
  {
    // Get the bbox of the polygon
    CGAL::Bbox_2 bbox = CGAL::bbox_2(star.begin(),star.end());

    // Compute the boundaries of the frame
    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)
                      } ;

    // Instantiate the skeleton builder
    SsBuilder ssb ;

    // Enter the frame
    ssb.enter_contour(frame,frame+4);

    // Enter the polygon as a hole of the frame (NOTE: as it is a hole we insert it in the opposite orientation)
    ssb.enter_contour(star.rbegin(),star.rend());

    // Construct the skeleton
    boost::shared_ptr<Ss> ss = ssb.construct_skeleton();

    // Proceed only if the skeleton was correctly constructed.
    if ( ss )
    {
      print_straight_skeleton(*ss);
      
      // Instantiate the container of offset contours
      ContourSequence offset_contours ;

      // Instantiate the offset builder with the skeleton
      OffsetBuilder ob(*ss);

      // Obtain the offset contours
      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 largetst unsigned area.
      ContourSequence::iterator f = offset_contours.end();
      double lLargestArea = 0.0 ;
      for (ContourSequence::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 ;
        }
      }

      // Remove the offset contour that corresponds to the frame.
      offset_contours.erase(f);
      
      print_polygons(offset_contours);
    }
  }

  return 0;
}
Example #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;
}
    // clears current internal nodes and generates new ones from the current state of the object
    void update_boundary_and_internal_nodes()
    {
        mBoundaryNodes.clear();
        mInternalNodes.clear();
        mMissingPopulationIndexMap.clear();
        mIsCurrentlyAnInternalNode.clear();

        CGAL::Bbox_2 boundingBox = mCircle->bbox();

        // iterate through bounding box nodes with 1 node lee way on all 4 sides
        for (int i = std::floor(CGAL::to_double(boundingBox.xmin())) - 2; i <= std::ceil(CGAL::to_double(boundingBox.xmax())) + 2; i++) {
            for (int j = std::floor(CGAL::to_double(boundingBox.ymin())) - 2; j <= std::ceil(CGAL::to_double(boundingBox.ymax())) + 2; j++) {

                // current point being checked
                Point query_point(i,j);

                // check if point is within the shape or right on the boundary
                if(!mCircle->has_on_unbounded_side(query_point) ||
                        mCircle->has_on_boundary(query_point))
                {
                    mInternalNodes.push_back(lb::coordinate<int>(i,j));
                    mIsCurrentlyAnInternalNode.push_back(make_pair(i,j));
                    continue;
                }

                bool is_boundary = false;
                vector<int> outGoingVelocityIndices;

                // check if the shape is on a boundary
                for (int velocity_index = 0; velocity_index < lb::velocity_set().size; velocity_index++)
                {
                    query_point = Point(i+lb::velocity_set().c[0][velocity_index],j+lb::velocity_set().c[1][velocity_index]);

                    if(!mCircle->has_on_unbounded_side(query_point) ||
                       mCircle->has_on_boundary(query_point))
                    {
                        // reflect the velocity index to get the corresponding outgoing velocity at the node
                        // and add it to the outgoing velocity indices of the current (boundary) node
                        outGoingVelocityIndices.push_back(lb::velocity_set().incoming_velocity_to_outgoing_velocity(velocity_index));
                        is_boundary = true;
                    }

                }

                // update boundary data
                if (is_boundary)
                {
                    mBoundaryNodes.push_back(lb::coordinate<int>(i,j));
                    mMissingPopulationIndexMap.insert(make_pair(make_pair(i,j),outGoingVelocityIndices));
                }

            }
        }


    }