diff --git a/Visibility_2/doc/Visibility_2/CGAL/Preprocessed_rotational_sweep_visibility_2.h b/Visibility_2/doc/Visibility_2/CGAL/Preprocessed_rotational_sweep_visibility_2.h index fcdea24da4e..04de7553262 100644 --- a/Visibility_2/doc/Visibility_2/CGAL/Preprocessed_rotational_sweep_visibility_2.h +++ b/Visibility_2/doc/Visibility_2/CGAL/Preprocessed_rotational_sweep_visibility_2.h @@ -45,14 +45,14 @@ public: typedef Input_arrangement_2::Point_2 Point_2; /*! - Face_handle type of the input arrangement. + Face_const_handle type of the input arrangement. */ - typedef Input_arrangement_2::Face_handle Face_handle; + typedef Input_arrangement_2::Face_const_handle Face_const_handle; /*! - Halfedge_handle type of the input arrangement. + Halfedge_const_handle type of the input arrangement. */ - typedef Input_arrangement_2::Halfedge_handle Halfedge_handle; + typedef Input_arrangement_2::Halfedge_const_handle Halfedge_const_handle; /// @} @@ -129,7 +129,7 @@ The visibility region of `q` will be stored in `out_arr`. \pre `q` is in the interior of the given face `f` \return a handle to the face in `out_arr` that represents the visibility region */ - Face_handle visibility_region(const Point_2& q, const Face_handle& f, Output_arrangement_2& out_arr); + Face_const_handle visibility_region(const Point_2& q, const Face_const_handle& f, Output_arrangement_2& out_arr); /*! Computes the visibility region for the given query point `q` that is on `e`.If `q` is an interior point of `e`, the computed visibility region is restricted to the halfplane indicated by `e`. If `q` is an endpoint of `e`, the visibility region is restricted by `e` and its next. @@ -142,7 +142,7 @@ The visibility region of `q` will be stored in `out_arr`. \pre `q` equals to `e->target()->point()` if `q` is an endpoint of `e` \return a handle to the face in `out_arr` that represents the visibility region */ - Face_handle visibility_region(const Point_2& q, const Halfedge_handle& e, Output_arrangement_2& out_arr); + Face_const_handle visibility_region(const Point_2& q, const Halfedge_const_handle& e, Output_arrangement_2& out_arr); /// @} diff --git a/Visibility_2/doc/Visibility_2/CGAL/Rotational_sweep_visibility_2.h b/Visibility_2/doc/Visibility_2/CGAL/Rotational_sweep_visibility_2.h index 46e39cbffd7..e76c4162996 100644 --- a/Visibility_2/doc/Visibility_2/CGAL/Rotational_sweep_visibility_2.h +++ b/Visibility_2/doc/Visibility_2/CGAL/Rotational_sweep_visibility_2.h @@ -43,14 +43,14 @@ public: typedef Input_arrangement_2::Point_2 Point_2; /*! - Face_handle type of the input arrangement. + Face_const_handle type of the input arrangement. */ - typedef Input_arrangement_2::Face_handle Face_handle; + typedef Input_arrangement_2::Face_const_handle Face_const_handle; /*! - Halfedge_handle type of the input arrangement. + Halfedge_const_handle type of the input arrangement. */ - typedef Input_arrangement_2::Halfedge_handle Halfedge_handle; + typedef Input_arrangement_2::Halfedge_const_handle Halfedge_const_handle; /// @} @@ -124,7 +124,7 @@ The visibility region of `q` will be stored in `out_arr`. \pre `q` is in the interior of the given face `f` \return a handle to the face in `out_arr` that represents the visibility region */ - Face_handle visibility_region(const Point_2& q, const Face_handle& f, Output_arrangement_2& out_arr); + Face_const_handle visibility_region(const Point_2& q, const Face_const_handle& f, Output_arrangement_2& out_arr); /*! Computes the visibility region for the given query point `q` that is on `e`.If `q` is an interior point of `e`, the computed visibility region is restricted to the halfplane indicated by `e`. If `q` is an endpoint of `e`, the visibility region is restricted by `e` and its next. @@ -137,7 +137,7 @@ The visibility region of `q` will be stored in `out_arr`. \pre `q` equals to `e->target()->point()` if `q` is an endpoint of `e` \return a handle to the face in `out_arr` that represents the visibility region */ - Face_handle visibility_region(const Point_2& q, const Halfedge_handle& e, Output_arrangement_2& out_arr); + Face_const_handle visibility_region(const Point_2& q, const Halfedge_const_handle& e, Output_arrangement_2& out_arr); /// @} diff --git a/Visibility_2/doc/Visibility_2/CGAL/Simple_polygon_visibility_2.h b/Visibility_2/doc/Visibility_2/CGAL/Simple_polygon_visibility_2.h index a9824b20561..7611c9a52ca 100644 --- a/Visibility_2/doc/Visibility_2/CGAL/Simple_polygon_visibility_2.h +++ b/Visibility_2/doc/Visibility_2/CGAL/Simple_polygon_visibility_2.h @@ -56,14 +56,14 @@ public: typedef Input_arrangement_2::Point_2 Point_2; /*! - Face_handle type of input arrangement. + Face_const_handle type of input arrangement. */ - typedef Input_arrangement_2::Face_handle Face_handle; + typedef Input_arrangement_2::Face_const_handle Face_const_handle; /*! - Halfedge_handle type of input arrangement. + Halfedge_const_handle type of input arrangement. */ - typedef Input_arrangement_2::Halfedge_handle Halfedge_handle; + typedef Input_arrangement_2::Halfedge_const_handle Halfedge_const_handle; /// @} @@ -140,7 +140,7 @@ The visibility region of `q` will be stored in `out_arr`. \pre `q` is in the interior of the given face `f` \return a handle to the face in `out_arr` that represents the visibility region */ - Face_handle visibility_region(const Point_2& q, const Face_handle& f, Output_arrangement_2& out_arr); + Face_const_handle visibility_region(const Point_2& q, const Face_const_handle& f, Output_arrangement_2& out_arr); /*! @@ -154,7 +154,7 @@ The visibility region of `q` will be stored in `out_arr`. \pre `q` equals to `e->target()->point()` if `q` is an endpoint of `e` \return a handle to the face in `out_arr` that represents the visibility region */ - Face_handle visibility_region(const Point_2& q, const Halfedge_handle& e, Output_arrangement_2& out_arr); + Face_const_handle visibility_region(const Point_2& q, const Halfedge_const_handle& e, Output_arrangement_2& out_arr); /// @} diff --git a/Visibility_2/doc/Visibility_2/CGAL/Triangular_expansion_visibility_2.h b/Visibility_2/doc/Visibility_2/CGAL/Triangular_expansion_visibility_2.h index 65419acc9bc..9833d39553e 100644 --- a/Visibility_2/doc/Visibility_2/CGAL/Triangular_expansion_visibility_2.h +++ b/Visibility_2/doc/Visibility_2/CGAL/Triangular_expansion_visibility_2.h @@ -45,14 +45,14 @@ public: typedef Input_arrangement_2::Point_2 Point_2; /*! - Face_handle type of the input arrangement. + Face_const_handle type of the input arrangement. */ - typedef Input_arrangement_2::Face_handle Face_handle; + typedef Input_arrangement_2::Face_const_handle Face_const_handle; /*! - Halfedge_handle type of the input arrangement. + Halfedge_const_handle type of the input arrangement. */ - typedef Input_arrangement_2::Halfedge_handle Halfedge_handle; + typedef Input_arrangement_2::Halfedge_const_handle Halfedge_const_handle; /// @} @@ -129,7 +129,7 @@ The visibility region of `q` will be stored in `out_arr`. \pre `q` is in the interior of the given face `f` \return a handle to the face in `out_arr` that represents the visibility region */ - Face_handle visibility_region(const Point_2& q, const Face_handle& f, Output_arrangement_2& out_arr); + Face_const_handle visibility_region(const Point_2& q, const Face_const_handle& f, Output_arrangement_2& out_arr); /*! @@ -143,7 +143,7 @@ The visibility region of `q` will be stored in `out_arr`. \pre `q` equals to `e->target()->point()` if `q` is an endpoint of `e` \return a handle to the face in `out_arr` that represents the visibility region */ - Face_handle visibility_region(const Point_2& q, const Halfedge_handle& e, Output_arrangement_2& out_arr); + Face_const_handle visibility_region(const Point_2& q, const Halfedge_const_handle& e, Output_arrangement_2& out_arr); /// @} diff --git a/Visibility_2/doc/Visibility_2/Concepts/Visibility_2.h b/Visibility_2/doc/Visibility_2/Concepts/Visibility_2.h index f9bbf732990..425b3ab8bf7 100644 --- a/Visibility_2/doc/Visibility_2/Concepts/Visibility_2.h +++ b/Visibility_2/doc/Visibility_2/Concepts/Visibility_2.h @@ -36,12 +36,12 @@ public: /*! * The supported Face handle type of the input arrangement. */ - typedef Input_arrangement_2::Face_handle Face_handle; + typedef Input_arrangement_2::Face_const_handle Face_const_handle; /*! * The supported Halfedge handle type of the input arrangement. */ - typedef Input_arrangement_2::Halfedge_handle Halfedge_handle; + typedef Input_arrangement_2::Halfedge_const_handle Halfedge_const_handle; /// @} @@ -117,7 +117,7 @@ The visibility region of `q` will be saved to `out_arr`. \pre `q` is in the interior of the given face `f` \return the face handle to the face in `out_arr` that represents the visibility region */ - Face_handle visibility_region(const Point_2& q, const Face_handle& f, Output_arrangement_2& out_arr); + Face_const_handle visibility_region(const Point_2& q, const Face_const_handle& f, Output_arrangement_2& out_arr); /*! Computes the visibility region for the given query point `q` that is on `e`.If `q` is an interior point of `e`, the computed visibility region is restricted to the halfplane indicated by `e`. If `q` is an endpoint of `e`, the visibility region is restricted by `e` and its next. @@ -130,7 +130,7 @@ The visibility region of `q` will be stored in `out_arr`. \pre `q` equals to `e->target()->point()` if `q` is an endpoint of `e` \return a handle to the face in `out_arr` that represents the visibility region */ - Face_handle visibility_region(const Point_2& q, const Halfedge_handle& e, Output_arrangement_2& out_arr); + Face_const_handle visibility_region(const Point_2& q, const Halfedge_const_handle& e, Output_arrangement_2& out_arr); /// @} diff --git a/Visibility_2/include/CGAL/Simple_polygon_visibility_2.h b/Visibility_2/include/CGAL/Simple_polygon_visibility_2.h index e8ff3d3f2d0..0d8eaf0a045 100644 --- a/Visibility_2/include/CGAL/Simple_polygon_visibility_2.h +++ b/Visibility_2/include/CGAL/Simple_polygon_visibility_2.h @@ -38,11 +38,10 @@ public: typedef Arrangement_2 Output_arrangement_2; typedef typename Arrangement_2::Geometry_traits_2 Geometry_traits_2; - typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle; typedef typename Arrangement_2::Halfedge_handle Halfedge_handle; typedef typename Arrangement_2::Ccb_halfedge_const_circulator Ccb_halfedge_const_circulator; - typedef typename Arrangement_2::Face_const_handle Face_const_handle; + typedef typename Arrangement_2::Face_handle Face_handle; typedef typename Geometry_traits_2::Point_2 Point_2; typedef typename Geometry_traits_2::Ray_2 Ray_2; @@ -84,7 +83,7 @@ public: return *p_arr; } - void visibility_region(Point_2 &q, const Face_const_handle face, + Face_handle visibility_region(Point_2 &q, const Face_handle face, Output_arrangement_2 &out_arr) { typename Input_arrangement_2::Ccb_halfedge_const_circulator circ = @@ -189,9 +188,14 @@ public: CGAL_precondition(s.size() == 0); conditional_regularize(out_arr, Regularization_tag()); vertices.clear(); + + if (out_arr.faces_begin()->is_unbounded()) + return ++out_arr.faces_begin(); + else + return out_arr.faces_begin(); } - void visibility_region(const Point_2 &q, const Halfedge_const_handle he, + Face_handle visibility_region(const Point_2 &q, const Halfedge_handle he, Output_arrangement_2 &out_arr ) { if (q != he->source()->point()) { @@ -265,6 +269,11 @@ public: CGAL_precondition(s.size() == 0); conditional_regularize(out_arr, Regularization_tag()); vertices.clear(); + + if (out_arr.faces_begin()->is_unbounded()) + return ++out_arr.faces_begin(); + else + return out_arr.faces_begin(); } void print_arrangement(const Arrangement_2 &arr) { diff --git a/Visibility_2/include/CGAL/Triangular_expansion_visibility_2_.h b/Visibility_2/include/CGAL/Triangular_expansion_visibility_2_.h new file mode 100644 index 00000000000..b425973cd7e --- /dev/null +++ b/Visibility_2/include/CGAL/Triangular_expansion_visibility_2_.h @@ -0,0 +1,294 @@ +// Copyright (c) 2013 Technical University Braunschweig (Germany). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s): Michael Hemmer +// + +#ifndef CGAL_TRIANGULAR_EXPANSION_VISIBILITY_2_H +#define CGAL_TRIANGULAR_EXPANSION_VISIBILITY_2_H + +#include +#include +#include + +namespace CGAL { + +template +class Triangular_expansion_visibility_2 { + typedef typename Arrangement_2::Geometry_traits_2 Geometry_traits_2; + typedef typename Geometry_traits_2::Kernel K; +public: + // Currently only consider with same type for both + typedef Arrangement_2 Input_arrangement_2; + typedef Arrangement_2 Output_arrangement_2; + typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle; + typedef typename Arrangement_2::Halfedge_handle Halfedge_handle; + typedef typename Arrangement_2::Ccb_halfedge_const_circulator + Ccb_halfedge_const_circulator; + typedef typename Arrangement_2::Face_const_handle Face_const_handle; + + typedef typename K::Point_2 Point_2; + 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 RegularizationTag Regularization_tag; + typedef CGAL::Tag_true Supports_general_polygon_tag; + typedef CGAL::Tag_true Supports_simple_polygon_tag; + +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_Delaunay_triangulation_2 CDT; + + +private: + const Input_arrangement_2* p_arr; + boost::shared_ptr p_cdt; + +public: + Triangular_expansion_visibility_2() : p_arr(NULL){} + + /*! Constructor given an arrangement and the Regularization tag. */ + Triangular_expansion_visibility_2 (const Input_arrangement_2 &arr) + : p_arr(&arr){ + init_cdt(); + } + + bool is_attached() { + return (p_arr != NULL); + } + + void attach(const Input_arrangement_2 &arr) { + p_arr = &arr; + init_cdt(); + } + + void detach() { + p_arr = NULL; + p_cdt = boost::shared_ptr(); + } + + const Input_arrangement_2& arr() { + return *p_arr; + } + + typename CDT::Edge get_edge(typename CDT::Face_handle fh, int i){ + return std::make_pair(fh,i); + } + + Point_2 ray_seg_intersection( + const Point_2& q, const Point_2& b, // the ray + const Point_2& s, const Point_2& t) // the segment + { + Ray_2 ray(q,b); + Segment_2 seg(s,t); + CGAL::Object obj = typename K::Intersect_2()(ray,seg); + return object_cast(obj); + } + + + template + OIT expand_edge( + const Point_2& q, + const Point_2& left, + const Point_2& right, + typename CDT::Face_handle fh, + int index, + OIT oit){ + + // go into the new face + typename CDT::Face_handle nfh = fh->neighbor(index); + + // get indices of neighbors + int nindex = nfh->index(fh); // index of new vertex and old face + int rindex = p_cdt->ccw(nindex); // index of face behind right edge + int lindex = p_cdt-> cw(nindex); // index of face behind left edge + + // get vertices seen from entering edge + typename CDT::Vertex_handle nvh = nfh->vertex(nindex); + typename CDT::Vertex_handle rvh = nfh->vertex(p_cdt->cw (nindex)); + typename CDT::Vertex_handle lvh = nfh->vertex(p_cdt->ccw(nindex)); + + // get edges seen from entering edge + typename CDT::Edge re = get_edge(nfh,p_cdt->ccw(nindex)); + typename CDT::Edge le = get_edge(nfh,p_cdt-> cw(nindex)); + + // do orientation computation once for new vertex + typename K::Orientation_2 orientation = + p_cdt->geom_traits().orientation_2_object(); + CGAL::Orientation ro = orientation(q,right,nvh->point()); + CGAL::Orientation lo = orientation(q,left ,nvh->point()); + + std::cout << q << std::endl + << right << std::endl + << left << std::endl + << nvh->point() << std::endl ; + + std::cout << (ro == CGAL::COUNTERCLOCKWISE) << " " << (lo == CGAL::CLOCKWISE) << std::endl; + + //right edge is seen if new vertex is counter clockwise of right boarder + if(ro == CGAL::COUNTERCLOCKWISE){ + if(p_cdt->is_constrained(re)){ + // the edge is constrained + // report intersection with right boarder ray + // if it is not already the right vertex (already reported) + if(right != rvh->point()){ + *oit++ = + ray_seg_intersection(q,right,nvh->point(),rvh->point()); + } + + // then report intersection with left boarder if it exists + if(lo == CGAL::COUNTERCLOCKWISE){ + *oit++ = + ray_seg_intersection(q,left,nvh->point(),rvh->point()); + } + }else{ + // the edge is not a constrained + if(lo == CGAL::COUNTERCLOCKWISE){ + // no split needed and return + return expand_edge(q,left,right,nfh,rindex,oit); + }else{ + // spliting at new vertex + oit = expand_edge(q,nvh->point(),right,nfh,rindex,oit); + } + } + } + + // determin whether new vertex needs to be reported + if(ro != CGAL::CLOCKWISE && lo != CGAL::COUNTERCLOCKWISE){ + *oit++ = nvh->point(); + } + + //left edge is seen if new vertex is clockwise of left boarder + if(lo == CGAL::CLOCKWISE){ + if(p_cdt->is_constrained(le)){ + // the edge is constrained + // report interesection with right boarder if exists + if(ro == CGAL::CLOCKWISE){ + *oit++ = ray_seg_intersection(q,right,nvh->point(),lvh->point()); + } + // then report intersection with left boarder ray + // if it is not already the left vertex (already reported) + if(left != lvh->point()) + *oit++ = + ray_seg_intersection(q,left,nvh->point(),lvh->point()); + return oit; + }else{ + // the edge is not a constrained + if(ro == CGAL::CLOCKWISE){ + // no split needed and return + return expand_edge(q,left,right,nfh,lindex,oit); + }else{ + // spliting at new vertex + return expand_edge(q,left,nvh->point(),nfh,rindex,oit); + } + } + } + + // never reached ;) + assert(false); + + } + + void visibility_region(Point_2 &q, + const Face_const_handle face, + Output_arrangement_2 &out_arr + ) { + std::cout <<" ======================== "<< std::endl ; + std::vector raw_output; + typename CDT::Face_handle cdt_face = p_cdt->locate(q); + + raw_output.push_back(cdt_face->vertex(1)->point()); + if(!p_cdt->is_constrained(get_edge(cdt_face,0))){ + std::cout << "edge 0 is not constrained" << std::endl; + expand_edge( + q, + cdt_face->vertex(2)->point(), + cdt_face->vertex(1)->point(), + cdt_face,0,std::back_inserter(raw_output)); + } + + raw_output.push_back(cdt_face->vertex(2)->point()); + if(!p_cdt->is_constrained(get_edge(cdt_face,1))){ + std::cout << "edge 1 is not constrained" << std::endl; + expand_edge( + q, + cdt_face->vertex(0)->point(), + cdt_face->vertex(2)->point(), + cdt_face,1,std::back_inserter(raw_output)); + } + + raw_output.push_back(cdt_face->vertex(0)->point()); + if(!p_cdt->is_constrained(get_edge(cdt_face,2))){ + std::cout << "edge 2 is not constrained" << std::endl; + expand_edge( + q, + cdt_face->vertex(1)->point(), + cdt_face->vertex(0)->point(), + cdt_face,2,std::back_inserter(raw_output)); + } + + std::cout << raw_output.size() << std::endl; + + // TODO: handle needles and report arr at same time + std::vector segments; + for(int i = 0; i > constraints; + for(typename Input_arrangement_2::Edge_const_iterator eit = p_arr->edges_begin(); + eit != p_arr->edges_end(); eit++){ + Point_2 source = eit->source()->point(); + Point_2 target = eit->target()->point(); + std::cout << source << " -- " << target << std::endl; + constraints.push_back(std::make_pair(source,target)); + } + p_cdt = boost::shared_ptr(new CDT(constraints.begin(),constraints.end())); + } +}; + +} // namespace CGAL + +#endif diff --git a/Visibility_2/include/CGAL/Visibility_2/visibility_utils.h b/Visibility_2/include/CGAL/Visibility_2/visibility_utils.h new file mode 100644 index 00000000000..988982f097f --- /dev/null +++ b/Visibility_2/include/CGAL/Visibility_2/visibility_utils.h @@ -0,0 +1,214 @@ +// Copyright (c) 2013 Technical University Braunschweig (Germany). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s): Francisc Bungiu +// Michael Hemmer + +#ifndef CGAL_VISIBILITY_UTILS_H +#define CGAL_VISIBILITY_UTILS_H + +#include +#include +#include + +namespace CGAL { +namespace Visibility_2 { + +template +void print_arrangement(const Arrangement_2 &arr) { + typedef typename Arrangement_2::Edge_const_iterator Edge_const_iterator; + Edge_const_iterator eit; + std::cout << arr.number_of_edges() << " edges:" << std::endl; + for (eit = arr.edges_begin(); eit != arr.edges_end(); ++eit) + std::cout << "[" << eit->curve() << "]" << std::endl; +} + +template +Orientation Orientation_2(const Geometry_traits_2 *geom_traits, + const typename Geometry_traits_2::Point_2 &p, + const typename Geometry_traits_2::Point_2 &q, + const typename Geometry_traits_2::Point_2 &r) { + + typename Geometry_traits_2::Orientation_2 orient = + geom_traits->orientation_2_object(); + return orient(p, q, r); +} + +template +bool LessDistanceToPoint_2(const Geometry_traits_2 *geom_traits, + const typename Geometry_traits_2::Point_2 &p, + const typename Geometry_traits_2::Point_2 &q, + const typename Geometry_traits_2::Point_2 &r) { + + typename Geometry_traits_2::Less_distance_to_point_2 less_dist = + geom_traits->less_distance_to_point_2_object(); + return less_dist(p, q, r); +} + +template +bool Collinear(const Geometry_traits_2 *geom_traits, + const typename Geometry_traits_2::Point_2 &p, + const typename Geometry_traits_2::Point_2 &q, + const typename Geometry_traits_2::Point_2 &r) { + + typename Geometry_traits_2::Collinear_2 collinear_fnct = + geom_traits->collinear_2_object(); + return collinear_fnct(p, q, r); +} + +template +typename Geometry_traits_2::Object_2 Intersect_2(const Geometry_traits_2 *geom_traits, + const _Curve_first &s1, + const _Curve_second &s2) { + + typedef typename Geometry_traits_2::Kernel Kernel; + const Kernel *kernel = static_cast (geom_traits); + typename Kernel::Intersect_2 intersect_fnct = kernel->intersect_2_object(); + return intersect_fnct(s1, s2); +} + +template +typename Geometry_traits_2::Point_2 Construct_projected_point_2( + const Geometry_traits_2 *geom_traits, + const typename Geometry_traits_2::Line_2 &l, + const typename Geometry_traits_2::Point_2 &p) { + + typename Geometry_traits_2::Construct_projected_point_2 construct_proj = + geom_traits->construct_projected_point_2_object(); + return construct_proj(l, p); +} + +template +typename Geometry_traits_2::FT Compute_squared_distance_2( + const Geometry_traits_2 *geom_traits, + const typename Geometry_traits_2::Point_2 &p, + const typename Geometry_traits_2::Segment_2 &seg) { + + typename Geometry_traits_2::Compute_squared_distance_2 compute_dist = + geom_traits->compute_squared_distance_2_object(); + return compute_dist(p, seg); +} + +template +void report_while_handling_needles( + const typename Visibility_2::Input_arrangement_2::Geometry_traits_2 *geom_traits, + std::vector &points, + const typename Visibility_2::Input_arrangement_2::Point_2 &q, + typename Visibility_2::Output_arrangement_2 &arr_out) { + + typedef typename Visibility_2::Input_arrangement_2 Input_arrangement_2; + typedef typename Input_arrangement_2::Point_2 Point_2; + typedef typename Input_arrangement_2::Geometry_traits_2 Geometry_traits_2; + typedef typename Geometry_traits_2::Segment_2 Segment_2; + typedef typename Geometry_traits_2::Direction_2 Direction_2; + + typename std::vector::size_type i = 0; + + while (Collinear(geom_traits, + points[i], + points[points.size()-1], + points[points.size()-2]) + || Collinear(geom_traits, + points[i], + points[i+1], + points[points.size()-1])) { + + points.push_back(points[i]); + i++; + } + + points.push_back(points[i]); + + std::vector forward_needle; + std::vector backward_needle; + std::vector segments; + + while (i+1 < points.size()) { + if ((i+2 < points.size()) && + (Orientation_2(geom_traits, + points[i], + points[i+1], + points[i+2]) == CGAL::COLLINEAR)) { + + Point_2 needle_start = points[i]; + Direction_2 forward_dir(Segment_2(points[i], points[i+1])); + forward_needle.push_back(points[i]); + forward_needle.push_back(points[i+1]); + + while ((i+2 < points.size()) && + (Orientation_2(geom_traits, + points[i], + points[i+1], + points[i+2]) == CGAL::COLLINEAR)) { + + Direction_2 check_dir(Segment_2(points[i+1], points[i+2])); + if (forward_dir == check_dir) { + forward_needle.push_back(points[i+2]); + } + else if (check_dir == -forward_dir) { + backward_needle.push_back(points[i+2]); + } + i++; + } + std::reverse(backward_needle.begin(), backward_needle.end()); + std::vector merged_needle; + + // Now merge the two vectors + unsigned int itr_fst = 0, itr_snd = 0; + while (itr_fst < forward_needle.size() && + itr_snd < backward_needle.size()) { + + if (LessDistanceToPoint_2(geom_traits, + q, + forward_needle[itr_fst], + backward_needle[itr_snd])) { + + merged_needle.push_back(forward_needle[itr_fst]); + itr_fst++; + } + else { + merged_needle.push_back(backward_needle[itr_snd]); + itr_snd++; + } + } + while (itr_fst < forward_needle.size()) { + merged_needle.push_back(forward_needle[itr_fst]); + itr_fst++; + } + while (itr_snd < backward_needle.size()) { + merged_needle.push_back(backward_needle[itr_snd]); + itr_snd++; + } + for (unsigned int p = 0 ; p+1 < merged_needle.size() ; p++) { + segments.push_back(Segment_2(merged_needle[p], merged_needle[p+1])); + } + } + else { + segments.push_back(Segment_2(points[i], points[i+1])); + } + i++; + } + CGAL::insert_non_intersecting_curves(arr_out, + segments.begin(), + segments.end()); +} + +} // end namespace Visibility_2 +} // end namespace CGAL + +#endif \ No newline at end of file diff --git a/Visibility_2/test/Visibility_2/benchmark.cpp b/Visibility_2/test/Visibility_2/benchmark.cpp index 6c08d9d3787..379e915c4e1 100644 --- a/Visibility_2/test/Visibility_2/benchmark.cpp +++ b/Visibility_2/test/Visibility_2/benchmark.cpp @@ -25,7 +25,7 @@ #include #include #include -//#include +#include #include #include #include @@ -43,7 +43,7 @@ int main() { typedef CGAL::Arrangement_2 Arrangement_2; typedef CGAL::Simple_polygon_visibility_2 Simple_polygon_visibility_2; - typedef CGAL::Simple_polygon_visibility_2 + typedef CGAL::Naive_visibility_2 Naive_visibility_2; // First read arrangement @@ -52,9 +52,9 @@ int main() { CGAL::create_arrangement_from_file(arr, input); Simple_polygon_visibility_2 simple_visibility; Naive_visibility_2 naive_visibility; - CGAL::QueryChoice qchoice; + CGAL::Query_choice qchoice; qchoice = CGAL::FACE; - typename Arrangement_2::Face_const_iterator fit; + typename Arrangement_2::Face_iterator fit; for (fit = arr.faces_begin(); fit != arr.faces_end(); ++fit) { if (!fit->is_unbounded()) { diff --git a/Visibility_2/test/Visibility_2/include/CGAL/test_model_methods.h b/Visibility_2/test/Visibility_2/include/CGAL/test_model_methods.h index 4b5933fad8a..5557e6bec8f 100644 --- a/Visibility_2/test/Visibility_2/include/CGAL/test_model_methods.h +++ b/Visibility_2/test/Visibility_2/include/CGAL/test_model_methods.h @@ -59,6 +59,7 @@ void test_model_methods_for_arr( // First consider query point in the unbounded face Point_2 query_pt(1, 1); visibility.visibility_region(query_pt, fit, arr_out); + assert(true == test_are_equal (arr, arr_out)); visibility.detach(); @@ -133,8 +134,7 @@ void test_model_methods() { CGAL::insert(arr_triangle, seg_tri.begin(), seg_tri.end()); test_model_methods_for_arr(arr_triangle); - } } // end CGAL namespace -#endif +#endif \ No newline at end of file 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 19a2d1137f7..36c307f272d 100644 --- a/Visibility_2/test/Visibility_2/include/CGAL/test_utils.h +++ b/Visibility_2/test/Visibility_2/include/CGAL/test_utils.h @@ -38,7 +38,7 @@ namespace CGAL { -enum QueryChoice {VERTEX, EDGE, FACE}; +enum Query_choice {VERTEX, EDGE, FACE}; template typename Arrangement_2::Halfedge_handle get_initial_halfedge(const Arrangement_2 &arr) { @@ -311,7 +311,6 @@ bool run_test_case_from_file(Visibility_2 visibility, std::ifstream &input) { (input, arr_correct_out)) { return false; } - CGAL::Object obj = CGAL::get_location(arr_in, query_pt); Face_const_handle f; Halfedge_const_handle e; @@ -340,7 +339,6 @@ bool run_test_case_from_file(Visibility_2 visibility, std::ifstream &input) { } } while (++he_curr != he_circ); } - if (!test_are_equal(arr_out, arr_correct_out)) { return false; } @@ -588,13 +586,13 @@ template void benchmark(Visibility_2_fst &visibility_fst, Visibility_2_snd &visibility_snd, const Arrangement_2 &arr, - typename Arrangement_2::Face_const_handle face, - QueryChoice choice) { + typename Arrangement_2::Face_handle face, + Query_choice choice) { - typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle; + typedef typename Arrangement_2::Halfedge_handle Halfedge_handle; typedef typename Arrangement_2::Geometry_traits_2 Geometry_traits_2; - typedef typename Arrangement_2::Ccb_halfedge_const_circulator - Ccb_halfedge_const_circulator; + typedef typename Arrangement_2::Ccb_halfedge_circulator + Ccb_halfedge_circulator; typedef typename Geometry_traits_2::Point_2 Point_2; typedef typename Geometry_traits_2::FT Number_type; typedef Timer Benchmark_timer; @@ -612,11 +610,11 @@ void benchmark(Visibility_2_fst &visibility_fst, timer.stop(); std::cout << "Time to attach to second object: " << timer.time() << std::endl; - Ccb_halfedge_const_circulator circ = face->outer_ccb(); - Ccb_halfedge_const_circulator curr = circ; + Ccb_halfedge_circulator circ = face->outer_ccb(); + Ccb_halfedge_circulator curr = circ; do { - Halfedge_const_handle he = curr; + Halfedge_handle he = curr; Point_2 curr_query_pt; bool selected_query_pt = true; switch (choice) { @@ -628,8 +626,8 @@ void benchmark(Visibility_2_fst &visibility_fst, (he->source()->point(), he->target()->point()); break; case FACE: - Ccb_halfedge_const_circulator curr_next = circ; - Halfedge_const_handle he_next = curr_next; + Ccb_halfedge_circulator curr_next = circ; + Halfedge_handle he_next = curr_next; Point_2 p1 = he->source()->point(); Point_2 p2 = he->target()->point(); Point_2 p3 = he_next->target()->point(); @@ -656,7 +654,7 @@ void benchmark(Visibility_2_fst &visibility_fst, visibility_fst.visibility_region(curr_query_pt, face, out_arr_fst); } else { - // visibility_fst.visibility_region(curr_query_pt, he, out_arr_fst); + visibility_fst.visibility_region(curr_query_pt, he, out_arr_fst); } timer.stop(); @@ -669,14 +667,14 @@ void benchmark(Visibility_2_fst &visibility_fst, visibility_snd.visibility_region(curr_query_pt, face, out_arr_snd); } else { -// visibility_snd.visibility_region(curr_query_pt, he, out_arr_snd); + visibility_snd.visibility_region(curr_query_pt, he, out_arr_snd); } timer.stop(); std::cout << "Time to compute visibility region using second object for " << curr_query_pt << " : " << timer.time() << std::endl; - visibility_fst.print_arrangement(out_arr_fst); - visibility_fst.print_arrangement(out_arr_snd); +// visibility_fst.print_arrangement(out_arr_fst); + // visibility_fst.print_arrangement(out_arr_snd); assert(true == (CGAL::test_are_equal (out_arr_fst, out_arr_snd))); } while (++curr != circ); diff --git a/Visibility_2/test/Visibility_2/test_simple_visibility.cpp b/Visibility_2/test/Visibility_2/test_simple_visibility.cpp index 3a0e5d1e76d..e2e0fc10dfc 100644 --- a/Visibility_2/test/Visibility_2/test_simple_visibility.cpp +++ b/Visibility_2/test/Visibility_2/test_simple_visibility.cpp @@ -45,7 +45,7 @@ int main() { Simple_polygon_visibility_2; CGAL::test_model_methods(); - std::cout << "Running test suite with Cartesian Kernel...\n"; + std::cout << "Running test suite with " << GREEN << "Cartesian" << RESET << " Kernel..." << std::endl; CGAL::run_tests(1); } { @@ -58,7 +58,7 @@ int main() { Simple_polygon_visibility_2; CGAL::test_model_methods(); - std::cout << "Running test suite with EPECK Kernel...\n"; + std::cout << "Running test suite with " << GREEN << "EPECK" << RESET << " Kernel..." << std::endl; CGAL::run_tests(1); } return 0; diff --git a/Visibility_2/test/Visibility_2/test_triangular_expansion_.cpp b/Visibility_2/test/Visibility_2/test_triangular_expansion_.cpp new file mode 100644 index 00000000000..1980af3eac4 --- /dev/null +++ b/Visibility_2/test/Visibility_2/test_triangular_expansion_.cpp @@ -0,0 +1,73 @@ +// Copyright (c) 2013 Technical University Braunschweig (Germany). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s): Francisc Bungiu +// Michael Hemmer + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +int main() { +{ + typedef CGAL::Gmpq Number_type; + typedef CGAL::Cartesian Kernel; + typedef CGAL::Arr_segment_traits_2 Traits_2; + typedef CGAL::Arrangement_2 Arrangement_2; + { + typedef CGAL::Triangular_expansion_visibility_2 + Visibility_2; + CGAL::test_model_methods(); + CGAL::run_tests(1); + } +// { +// typedef CGAL::Triangular_expansion_visibility_2 +// Visibility_2; +// CGAL::test_model_methods(); +// CGAL::run_tests(1); +// } +} +{ + typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel; + typedef CGAL::Arr_segment_traits_2 Traits_2; + typedef CGAL::Arrangement_2 Arrangement_2; +// { +// typedef CGAL::Triangular_expansion_visibility_2 +// Visibility_2; +// CGAL::test_model_methods(); +// CGAL::run_tests(1); +// } +// { +// typedef CGAL::Triangular_expansion_visibility_2 +// Visibility_2; +// CGAL::test_model_methods(); +// CGAL::run_tests(1); +// } +} +return 0; +}