//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; }
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); }
// 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)); } } } }
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); }
virtual QRectF boundingRect() const { return QRectF(_bb.xmin(), _bb.ymin(), _bb.xmax() - _bb.xmin(), _bb.ymax() - _bb.ymin()); }
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); }
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; }
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; }