From a4f7e1bd3fd65a1e53648b3da89859042d5750de Mon Sep 17 00:00:00 2001 From: Andreas Haas Date: Thu, 14 May 2015 15:17:42 +0200 Subject: [PATCH 1/4] Fixed sign-conversion warnings. --- .../CGAL/Rotational_sweep_visibility_2.h | 26 +++++++++---------- .../Visibility_2/include/CGAL/test_utils.h | 6 +++-- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/Visibility_2/include/CGAL/Rotational_sweep_visibility_2.h b/Visibility_2/include/CGAL/Rotational_sweep_visibility_2.h index 6008e37a4c3..eb107502d21 100644 --- a/Visibility_2/include/CGAL/Rotational_sweep_visibility_2.h +++ b/Visibility_2/include/CGAL/Rotational_sweep_visibility_2.h @@ -451,16 +451,16 @@ private: } //arrange vertices that on a same vision ray in a 'funnel' order - void funnel(int i, int j) const { + void funnel(typename VHs::size_type i, typename VHs::size_type j) const { VHs right, left; //whether the edges incident to a vertex block the left side and right side //of current vision ray. bool block_left(false), block_right(false); VH former = vs[i], nb; - for (int l=i; lsource()->point(), relevant_edges[i]->target()->point())) active_edges.insert(relevant_edges[i]); @@ -561,12 +561,12 @@ private: //angular sweep begins // std::cout<point(), vs[j]->point())) break; @@ -860,7 +860,7 @@ private: //the vision ray will always intersect at least an edge. //this box doesn't intersect any relevant_edge. Points points; - for (int i=0; ipoint()); } points.push_back(q); @@ -907,8 +907,8 @@ private: std::sort(vs.begin(), vs.end(), Is_swept_earlier(q, geom_traits)); - for (int i=0; i!=vs.size(); i++) { - int j = i+1; + for (typename VHs::size_type i=0; i!=vs.size(); i++) { + typename VHs::size_type j = i+1; while (j != vs.size()) { if (!CGAL::collinear(q, vs[i]->point(), vs[j]->point())) break; diff --git a/Visibility_2/test/Visibility_2/include/CGAL/test_utils.h b/Visibility_2/test/Visibility_2/include/CGAL/test_utils.h index 441cd0bda4e..5b913cc8753 100644 --- a/Visibility_2/test/Visibility_2/include/CGAL/test_utils.h +++ b/Visibility_2/test/Visibility_2/include/CGAL/test_utils.h @@ -735,7 +735,7 @@ void create_arrangement_from_env_file(_Arrangement_2 &arr, std::ifstream& input) std::getline(input, line); std::stringstream convert(line); - int number_of_vertices; + typename std::vector::size_type number_of_vertices; convert >> number_of_vertices; for (int j = 0; j < number_of_vertices; j++) { std::getline(input, line); @@ -745,7 +745,9 @@ void create_arrangement_from_env_file(_Arrangement_2 &arr, std::ifstream& input) points.push_back(Point_2(string2num(n1), string2num(n2))); } - for (int j = 0; j < number_of_vertices-1 ; j++) { + for (typename std::vector::size_type j = 0; + j < number_of_vertices-1 ; j++) + { segments.push_back(Segment_2(points[j], points[j+1])); } segments.push_back(Segment_2(points.front(), points.back())); From ee343b08006bbea6cd94de5c70dbc7039f31f558 Mon Sep 17 00:00:00 2001 From: Andreas Haas Date: Mon, 18 May 2015 15:16:44 +0200 Subject: [PATCH 2/4] Fixed performance bug. --- .../CGAL/Simple_polygon_visibility_2.h | 127 ++++++++---------- 1 file changed, 53 insertions(+), 74 deletions(-) diff --git a/Visibility_2/include/CGAL/Simple_polygon_visibility_2.h b/Visibility_2/include/CGAL/Simple_polygon_visibility_2.h index c15daee0261..ccbb0610d53 100644 --- a/Visibility_2/include/CGAL/Simple_polygon_visibility_2.h +++ b/Visibility_2/include/CGAL/Simple_polygon_visibility_2.h @@ -26,14 +26,12 @@ #include #include #include -#include #include +#include #include #include -#include // TODO: -// * rm DT = O(n^2) // * fix handle needles = O(nlogn) namespace CGAL { @@ -49,6 +47,7 @@ public: typedef typename K::Intersect_2 Intersect_2; + typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle; typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle; typedef typename Arrangement_2::Halfedge_handle Halfedge_handle; @@ -63,9 +62,6 @@ public: typedef typename Geometry_traits_2::Ray_2 Ray_2; typedef typename Geometry_traits_2::Segment_2 Segment_2; typedef typename Geometry_traits_2::Line_2 Line_2; - typedef typename Geometry_traits_2::Vector_2 Vector_2; - typedef typename Geometry_traits_2::Direction_2 Direction_2; - typedef typename Geometry_traits_2::FT Number_type; typedef typename Geometry_traits_2::Object_2 Object_2; typedef RegularizationCategory Regularization_category; @@ -78,8 +74,10 @@ public: Simple_polygon_visibility_2(const Arrangement_2& arr): p_arr(&arr) { traits = p_arr->geometry_traits(); + point_location.attach(arr); query_pt_is_vertex = false; query_pt_is_on_halfedge = false; + inserted_artificial_starting_vertex = false; } @@ -97,18 +95,20 @@ public: detach(); p_arr = &arr; traits = p_arr->geometry_traits(); + point_location.attach(arr); } } /*! Detaches the visibility object from the arrangement it is attached to*/ void detach() { + point_location.detach(); p_arr = NULL; traits = NULL; vertices.clear(); query_pt_is_vertex = false; query_pt_is_on_halfedge = false; - p_cdt.reset(); + inserted_artificial_starting_vertex = false; } /*! Getter method for the input arrangement*/ @@ -131,6 +131,7 @@ public: query_pt_is_vertex = false; query_pt_is_on_halfedge = false; + inserted_artificial_starting_vertex = false; // Now retrieve the circulator to first visible vertex from triangulation Ccb_halfedge_const_circulator circ = find_visible_start(face, q); @@ -197,11 +198,8 @@ public: } private: - typedef CGAL::Triangulation_vertex_base_2 Vb; - typedef CGAL::Constrained_triangulation_face_base_2 Fb; - typedef CGAL::Triangulation_data_structure_2 TDS; - typedef CGAL::No_intersection_tag Itag; - typedef CGAL::Constrained_triangulation_2 CDT; + typedef Arr_walk_along_line_point_location Arr_point_location; + typedef typename Arr_point_location::result_type Location_result; typedef std::vector Vertex_container; typedef typename Vertex_container::size_type Size_type; @@ -209,11 +207,8 @@ private: const Arrangement_2 *p_arr; const Geometry_traits_2 *traits; - /*! Boost pointer to the constrained Delaunay triangulation object*/ - mutable boost::shared_ptr p_cdt; - /*! Mapping of the vertices of the input to the corresponding circulator - needed for finding the first visible vertex in case of face queries*/ - mutable std::map point_itr_map; + mutable Arr_point_location point_location; + /*! Stack of visibile points; manipulated when going through the sequence of input vertices; contains the vertices of the visibility region after the run of the algorithm*/ @@ -224,46 +219,30 @@ private: mutable enum {LEFT, RIGHT, SCANA, SCANB, SCANC, SCAND, FINISH} upcase; mutable bool query_pt_is_vertex; mutable bool query_pt_is_on_halfedge; - - - /*! Initialized the constrained Delaunay triangulation using the edges of - the outer boundary of 'face' */ - void init_cdt(const Face_const_handle &face) const { - - point_itr_map.clear(); - - std::vector > constraints; - Ccb_halfedge_const_circulator circ = face->outer_ccb(); - Ccb_halfedge_const_circulator curr = circ; - - do { - const Point_2& source = curr->source()->point(); - const Point_2& target = curr->target()->point(); - point_itr_map.insert(std::make_pair(source, curr)); - constraints.push_back(std::make_pair(source, target)); - } while(++curr != circ); - - p_cdt = boost::shared_ptr(new CDT(constraints.begin(), - constraints.end())); - } + mutable bool inserted_artificial_starting_vertex; template typename VARR::Face_handle output(const Point_2& q, VARR& out_arr) const { + if(inserted_artificial_starting_vertex) + stack.pop(); + std::vector points; while(!stack.empty()) { const Point_2& top = stack.top(); - if (top != q) { - points.push_back(top); - } - else if (query_pt_is_vertex) { - points.push_back(top); + if (top != q || query_pt_is_vertex) { + points.push_back(top); } stack.pop(); } + if(inserted_artificial_starting_vertex) { + points.back() = points[0]; + inserted_artificial_starting_vertex = false; + } + // Quick fix for now. Can be done faster. std::vector segments; @@ -298,41 +277,41 @@ private: /*! Finds a visible vertex from the query point 'q' in 'face' to start the algorithm from*/ Ccb_halfedge_const_circulator find_visible_start(Face_const_handle face, - const Point_2 &q) const { - init_cdt(face); - typename CDT::Face_handle fh = p_cdt->locate(q); - const Point_2& start_point = fh->vertex(0)->point(); + const Point_2 &q) const + { + Location_result result = point_location.ray_shoot_up(q); - // Now retrieve the circulator to first visible vertex from triangulation - Ccb_halfedge_const_circulator circ = point_itr_map[start_point]; + if(const Halfedge_const_handle* e = + boost::get(&(result))) + { + CGAL_assertion((*e)->face() == face); + Point_2 p(q.x(), + traits->compute_y_at_x_2_object()( + Line_2((*e)->source()->point(), + (*e)->target()->point()) , + q.x())); - Halfedge_around_vertex_const_circulator incident_circ = - circ->source()->incident_halfedges(); - Halfedge_around_vertex_const_circulator incident_curr = incident_circ; + vertices.push_back(p); + inserted_artificial_starting_vertex = true; - Ccb_halfedge_const_circulator incident_next; - - do { - - if (incident_curr->face() == face) { - incident_next = incident_curr; - ++incident_next; - - if (traits->orientation_2_object()( - incident_curr->source()->point(), - incident_curr->target()->point(), - q) == LEFT_TURN - || traits->orientation_2_object()( - incident_next->source()->point(), - incident_next->target()->point(), - q) == LEFT_TURN) - { - break; - } + return (*e)->next()->ccb(); } - } while (++incident_curr != incident_circ); + else if (const Vertex_const_handle* v = + boost::get(&(result))) + { + Halfedge_around_vertex_const_circulator cir = + (*v)->incident_halfedges(); - return incident_next; + while(face != cir->face()) { + ++cir; + } + return cir->next()->ccb(); + } + else + { + CGAL_assertion_msg(false, "Should not be reachable."); + return Ccb_halfedge_const_circulator(); + } } From 88a761f9a6343065ed9799cccc82fb3dcd75dca8 Mon Sep 17 00:00:00 2001 From: Andreas Haas Date: Wed, 20 May 2015 17:38:21 +0200 Subject: [PATCH 3/4] Fixed some warnings. --- .../CGAL/Rotational_sweep_visibility_2.h | 10 +- .../Visibility_2/include/CGAL/test_utils.h | 138 +++--------------- 2 files changed, 30 insertions(+), 118 deletions(-) diff --git a/Visibility_2/include/CGAL/Rotational_sweep_visibility_2.h b/Visibility_2/include/CGAL/Rotational_sweep_visibility_2.h index eb107502d21..6fcade4ad63 100644 --- a/Visibility_2/include/CGAL/Rotational_sweep_visibility_2.h +++ b/Visibility_2/include/CGAL/Rotational_sweep_visibility_2.h @@ -26,6 +26,7 @@ #include #include #include +#include namespace CGAL { @@ -362,8 +363,11 @@ public: } } - typename Points::iterator first = polygon.begin() + small_idx; - typename Points::iterator last = polygon.begin() + big_idx; + typename Points::iterator first = polygon.begin(); + std::advance(first, small_idx); + typename Points::iterator last = polygon.begin(); + std::advance(last, big_idx); + if (is_between) { Points polygon_out(first, last+1); if (is_vertex_query) @@ -780,7 +784,7 @@ private: //for vertex and edge query: the visibility is limited in a cone. void input_edge(const Halfedge_const_handle e, EHs& good_edges) const { - for (int i=0; itarget(); diff --git a/Visibility_2/test/Visibility_2/include/CGAL/test_utils.h b/Visibility_2/test/Visibility_2/include/CGAL/test_utils.h index 5b913cc8753..26c335e5afe 100644 --- a/Visibility_2/test/Visibility_2/include/CGAL/test_utils.h +++ b/Visibility_2/test/Visibility_2/include/CGAL/test_utils.h @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include @@ -151,28 +150,7 @@ bool test_are_equal(const ARR1 &arr1, const ARR2 &arr2) { return true; } -template -Number_type string2num(const std::string& s) { - typename std::string::size_type i; - if (s.find("/") != std::string::npos) { - i = s.find("/"); - std::string p = s.substr(0, i); - std::string q = s.substr(i+1); - std::stringstream convert(p); - int n, d; - convert >> n; - std::stringstream convert2(q); - convert2 >> d; - return Number_type(n)/Number_type(d); - } - else { - std::stringstream convert(s); - double n; - convert >> n; - return Number_type(n); - } -} template std::string num2string(Number_type& n) { @@ -223,11 +201,9 @@ bool create_arrangement_from_dat_file(std::ifstream &input, typedef typename Arrangement_2::Face_handle Face_handle; typedef typename Geometry_traits_2::Segment_2 Segment_2; typedef typename Geometry_traits_2::Point_2 Point_2; - typedef typename Geometry_traits_2::FT Number_type; if (input) { std::string curr_line; - std::vector isolated_vertices; std::getline(input, curr_line); std::stringstream convert(curr_line); int number_of_isolated_vertices; @@ -236,11 +212,9 @@ bool create_arrangement_from_dat_file(std::ifstream &input, for (int i = 0 ; i < number_of_isolated_vertices ; i++) { std::getline(input, curr_line); std::istringstream iss(curr_line); - std::string x, y; - iss >> x >> y; - arr.insert_in_face_interior(Point_2(string2num(x), - string2num(y)), - uface); + Point_2 p; + iss >> p; + arr.insert_in_face_interior(p, uface); } std::vector edges; int number_of_edges; @@ -249,13 +223,10 @@ bool create_arrangement_from_dat_file(std::ifstream &input, convert2 >> number_of_edges; for (int i = 0 ; i < number_of_edges ; i++) { std::getline(input, curr_line); - std::string x1, y1, x2, y2; std::istringstream iss(curr_line); - iss >> x1 >> y1 >> x2 >> y2; - edges.push_back(Segment_2(Point_2(string2num(x1), - string2num(y1)), - Point_2(string2num(x2), - string2num(y2)))); + Segment_2 seg; + iss >> seg; + edges.push_back(seg); } CGAL::insert(arr, edges.begin(), edges.end()); return true; @@ -294,43 +265,12 @@ void regularize(Arrangement_2& arr){ //std::cout << "regularize done" << std::endl; } -template -bool is_regular_arr(Arrangement_2& arr){ - //std::cout << "\n regularize" << std::endl; - // remove all edges with the same face on both sides - typedef typename Arrangement_2::Edge_iterator EIT; - for(EIT eit = arr.edges_begin(); eit != arr.edges_end();){ - if(eit->face() == eit->twin()->face()){ - // arr.remove_edge(eit++,false,false); did not compile - EIT eh = eit; - ++eit; - return false; - }else{ - ++eit; - } - } - // remove all isolated vertices (also those left from prvious step) - typedef typename Arrangement_2::Vertex_iterator VIT; - for(VIT vit = arr.vertices_begin(); vit != arr.vertices_end();){ - if(vit->degree()== 0){ - VIT vh = vit; - vit++; - return false; - }else{ - vit++; - } - } - return true; - //std::cout << "regularize done" << std::endl; -} - template bool run_test_case_from_file(Visibility_2& visibility, std::ifstream &input) { typedef typename Visibility_2::Arrangement_2 Arrangement_2; typedef typename Arrangement_2::Geometry_traits_2 Geometry_traits_2; typedef typename Geometry_traits_2::Point_2 Point_2; - typedef typename Geometry_traits_2::FT Number_type; typedef typename Arrangement_2::Halfedge_around_vertex_const_circulator Halfedge_around_vertex_const_circulator; typedef typename Arrangement_2::Face_const_handle Face_const_handle; @@ -346,17 +286,14 @@ bool run_test_case_from_file(Visibility_2& visibility, std::ifstream &input) { if (curr_line[0] != '#' && curr_line[0] != '/') break; } - std::stringstream convert(curr_line); - std::string x, y; - convert >> x >> y; - Point_2 query_pt(string2num(x), - string2num(y)); + std::stringstream ss(curr_line); + Point_2 query_pt; + ss >> query_pt; + std::getline(input, curr_line); - std::string x1, y1; std::istringstream iss(curr_line); - iss >> x1 >> y1; - Point_2 reference_pt(string2num(x1), - string2num(y1)); + Point_2 reference_pt; + iss >> reference_pt; std::getline(input, curr_line); if (!create_arrangement_from_dat_file(input, arr_in)) { @@ -677,7 +614,7 @@ void create_arrangement_from_file(_Arrangement_2 &arr, std::ifstream& input) { typedef typename Arrangement_2::Geometry_traits_2 Geometry_traits_2; typedef typename Geometry_traits_2::Segment_2 Segment_2; typedef typename Geometry_traits_2::Point_2 Point_2; - typedef typename Geometry_traits_2::FT Number_type; + if (input) { std::string line; while (std::getline(input, line)) { @@ -692,11 +629,10 @@ void create_arrangement_from_file(_Arrangement_2 &arr, std::ifstream& input) { for (int i = 0; i != number_of_points; i++) { std::getline(input, line); - std::string n1, n2; std::istringstream iss(line); - iss>> n1 >> n2; - points.push_back(Point_2(string2num(n1), - string2num(n2))); + Point_2 p; + iss >> p; + points.push_back(p); } int number_of_edges; input >> number_of_edges; @@ -719,7 +655,7 @@ void create_arrangement_from_env_file(_Arrangement_2 &arr, std::ifstream& input) typedef typename Arrangement_2::Geometry_traits_2 Geometry_traits_2; typedef typename Geometry_traits_2::Segment_2 Segment_2; typedef typename Geometry_traits_2::Point_2 Point_2; - typedef typename Geometry_traits_2::FT Number_type; + if (input) { std::string line; while (std::getline(input, line)) { @@ -737,13 +673,13 @@ void create_arrangement_from_env_file(_Arrangement_2 &arr, std::ifstream& input) std::stringstream convert(line); typename std::vector::size_type number_of_vertices; convert >> number_of_vertices; - for (int j = 0; j < number_of_vertices; j++) { + for (typename std::vector::size_type j = 0; + j < number_of_vertices; j++) { std::getline(input, line); - std::string n1, n2; std::istringstream iss(line); - iss >> n1 >> n2; - points.push_back(Point_2(string2num(n1), - string2num(n2))); + Point_2 p; + iss >> p; + points.push_back(p); } for (typename std::vector::size_type j = 0; j < number_of_vertices-1 ; j++) @@ -967,19 +903,7 @@ typename Arrangement_2::Face_const_handle construct_biggest_arr_with_no_holes( } } } - Ccb_halfedge_const_circulator circ_p = fch->outer_ccb(); - Ccb_halfedge_const_circulator curr_p = circ_p; - Halfedge_const_handle he_p;/* - std::cout << "OUT FACE\n"; - do { - he_p = curr_p; - Ccb_halfedge_const_circulator next = curr_p; - next++; - Halfedge_const_handle h_next = next; - assert(he_p->target() == h_next->source()); - std::cout << he_p->source()->point() << std::endl; - } while(++curr_p != circ_p); - std::cout << "END\n";*/ + return fch; } @@ -1338,22 +1262,6 @@ void pure_benchmark( Visibility_2 &visibility, // std::cout << "total time is:" << ptime + qtime << " sec" << std::endl; } -template -int intersect_seg(const Segment_2& seg1, const Segment_2& seg2, Segment_2& seg_out, Point_2& p_out) -{ - CGAL::Object result = CGAL::intersection(seg1, seg2); - if (const Point_2 *ipoint = CGAL::object_cast(&result)) { - p_out = *ipoint; - return 1; - } else - if (const Segment_2 *iseg = CGAL::object_cast(&result)) { - seg_out = *iseg; - return 2; - } else { - return 0; - } -} - template void test_star_shape_one_face( typename Visibility_2::Arrangement_2 &arr, From 6dce1a765dcc926c0ea2509cdd6fbdeb70a275c7 Mon Sep 17 00:00:00 2001 From: Andreas Haas Date: Mon, 8 Jun 2015 14:36:18 +0200 Subject: [PATCH 4/4] Workaround for min/max macros in windef.h --- Visibility_2/include/CGAL/Rotational_sweep_visibility_2.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Visibility_2/include/CGAL/Rotational_sweep_visibility_2.h b/Visibility_2/include/CGAL/Rotational_sweep_visibility_2.h index 6fcade4ad63..b73060ab28c 100644 --- a/Visibility_2/include/CGAL/Rotational_sweep_visibility_2.h +++ b/Visibility_2/include/CGAL/Rotational_sweep_visibility_2.h @@ -881,10 +881,10 @@ private: //make the box a little bigger than bb so that it won't intersect any //relevant_edge. - xmin = compute_x(bb.min())-1; - ymin = compute_y(bb.min())-1; - xmax = compute_x(bb.max())+1; - ymax = compute_y(bb.max())+1; + xmin = compute_x((bb.min)())-1; + ymin = compute_y((bb.min)())-1; + xmax = compute_x((bb.max)())+1; + ymax = compute_y((bb.max)())+1; Point_2 box[4] = {Point_2(xmin, ymin), Point_2(xmax, ymin), Point_2(xmax, ymax), Point_2(xmin, ymax)};