Merge branch 'gsoc2013-Visibility_doc-hemmer' of ssh://scm.cgal.org/var/git/cgal-gsoc into gsoc2013-Visibility_doc-hemmer

This commit is contained in:
kanhuang 2013-08-07 09:05:45 -04:00
commit d35c8c0834
13 changed files with 645 additions and 57 deletions

View File

@ -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);
/// @}

View File

@ -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);
/// @}

View File

@ -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);
/// @}

View File

@ -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);
/// @}

View File

@ -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);
/// @}

View File

@ -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) {

View File

@ -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 <michael.hemmer@cgal.org>
//
#ifndef CGAL_TRIANGULAR_EXPANSION_VISIBILITY_2_H
#define CGAL_TRIANGULAR_EXPANSION_VISIBILITY_2_H
#include <CGAL/Arrangement_2.h>
#include <boost/shared_ptr.hpp>
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
namespace CGAL {
template<class Arrangement_2,class RegularizationTag>
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<K> Vb;
typedef CGAL::Constrained_triangulation_face_base_2<K> Fb;
typedef CGAL::Triangulation_data_structure_2<Vb,Fb> TDS;
typedef CGAL::No_intersection_tag Itag;
typedef CGAL::Constrained_Delaunay_triangulation_2<K, TDS, Itag> CDT;
private:
const Input_arrangement_2* p_arr;
boost::shared_ptr<CDT> 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<CDT>();
}
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<Point_2>(obj);
}
template<class OIT>
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<Point_2> 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<Segment_2> segments;
for(int i = 0; i <raw_output.size();i++){
std::cout << raw_output[i] << std::endl;
segments.push_back(Segment_2(raw_output[i],raw_output[(i+1)%raw_output.size()]));
}
// use something more clever
CGAL::insert(out_arr,segments.begin(),segments.end());
std::cout << out_arr.number_of_faces() << std::endl;
assert(out_arr.number_of_faces()== 2);
}
void visibility_region(const Point_2 &q,
const Halfedge_const_handle he,
Output_arrangement_2 &out_arr
) {
}
void init_cdt(){
std::cout << "init_cdt" <<std::endl;
//todo, avoid copy by using modified iterator
std::vector<std::pair<Point_2,Point_2> > 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<CDT>(new CDT(constraints.begin(),constraints.end()));
}
};
} // namespace CGAL
#endif

View File

@ -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 <fbungiu@gmail.com>
// Michael Hemmer <michael.hemmer@cgal.org>
#ifndef CGAL_VISIBILITY_UTILS_H
#define CGAL_VISIBILITY_UTILS_H
#include <vector>
#include <CGAL/tags.h>
#include <CGAL/enum.h>
namespace CGAL {
namespace Visibility_2 {
template <class Arrangement_2>
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 <class Geometry_traits_2>
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 <class Geometry_traits_2>
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 <class Geometry_traits_2>
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 <class Geometry_traits_2, class _Curve_first, class _Curve_second >
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<const Kernel*> (geom_traits);
typename Kernel::Intersect_2 intersect_fnct = kernel->intersect_2_object();
return intersect_fnct(s1, s2);
}
template <class Geometry_traits_2>
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 <class Geometry_traits_2>
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 <class Visibility_2>
void report_while_handling_needles(
const typename Visibility_2::Input_arrangement_2::Geometry_traits_2 *geom_traits,
std::vector<typename Visibility_2::Input_arrangement_2::Point_2> &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<Segment_2>::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<Point_2> forward_needle;
std::vector<Point_2> backward_needle;
std::vector<Segment_2> 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<Point_2> 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

View File

@ -25,7 +25,7 @@
#include <CGAL/Arr_segment_traits_2.h>
#include <CGAL/Arrangement_2.h>
#include <CGAL/Simple_polygon_visibility_2.h>
//#include <CGAL/Naive_visibility_2.h>
#include <CGAL/Naive_visibility_2.h>
#include <CGAL/test_model_methods.h>
#include <CGAL/test_utils.h>
#include <CGAL/test_simple_polygons.h>
@ -43,7 +43,7 @@ int main() {
typedef CGAL::Arrangement_2<Traits_2> Arrangement_2;
typedef CGAL::Simple_polygon_visibility_2<Arrangement_2, CGAL::Tag_false>
Simple_polygon_visibility_2;
typedef CGAL::Simple_polygon_visibility_2<Arrangement_2, CGAL::Tag_false>
typedef CGAL::Naive_visibility_2<Arrangement_2, CGAL::Tag_false>
Naive_visibility_2;
// First read arrangement
@ -52,9 +52,9 @@ int main() {
CGAL::create_arrangement_from_file<Arrangement_2>(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()) {

View File

@ -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<Output_arrangement_2>
(arr, arr_out));
visibility.detach();
@ -133,7 +134,6 @@ void test_model_methods() {
CGAL::insert(arr_triangle, seg_tri.begin(), seg_tri.end());
test_model_methods_for_arr<Visibility_2>(arr_triangle);
}
} // end CGAL namespace

View File

@ -38,7 +38,7 @@
namespace CGAL {
enum QueryChoice {VERTEX, EDGE, FACE};
enum Query_choice {VERTEX, EDGE, FACE};
template <class Arrangement_2>
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<Input_arrangement_2>(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<Output_arrangement_2>(arr_out, arr_correct_out)) {
return false;
}
@ -588,13 +586,13 @@ template<class Visibility_2_fst, class Visibility_2_snd, class Arrangement_2>
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<Arrangement_2>
(out_arr_fst, out_arr_snd)));
} while (++curr != circ);

View File

@ -45,7 +45,7 @@ int main() {
Simple_polygon_visibility_2;
CGAL::test_model_methods<Simple_polygon_visibility_2>();
std::cout << "Running test suite with Cartesian Kernel...\n";
std::cout << "Running test suite with " << GREEN << "Cartesian" << RESET << " Kernel..." << std::endl;
CGAL::run_tests<Simple_polygon_visibility_2>(1);
}
{
@ -58,7 +58,7 @@ int main() {
Simple_polygon_visibility_2;
CGAL::test_model_methods<Simple_polygon_visibility_2>();
std::cout << "Running test suite with EPECK Kernel...\n";
std::cout << "Running test suite with " << GREEN << "EPECK" << RESET << " Kernel..." << std::endl;
CGAL::run_tests<Simple_polygon_visibility_2>(1);
}
return 0;

View File

@ -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 <fbungiu@gmail.com>
// Michael Hemmer <michael.hemmer@cgal.org>
#include <CGAL/basic.h>
#include <CGAL/Cartesian.h>
#include <CGAL/Gmpq.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Arr_segment_traits_2.h>
#include <CGAL/Arrangement_2.h>
#include <CGAL/test_model_methods.h>
#include <CGAL/test_utils.h>
#include <CGAL/test_simple_polygons.h>
#include <CGAL/Triangular_expansion_visibility_2_.h>
#include <iostream>
#include <fstream>
int main() {
{
typedef CGAL::Gmpq Number_type;
typedef CGAL::Cartesian<Number_type> Kernel;
typedef CGAL::Arr_segment_traits_2<Kernel> Traits_2;
typedef CGAL::Arrangement_2<Traits_2> Arrangement_2;
{
typedef CGAL::Triangular_expansion_visibility_2<Arrangement_2, CGAL::Tag_false>
Visibility_2;
CGAL::test_model_methods<Visibility_2>();
CGAL::run_tests<Visibility_2>(1);
}
// {
// typedef CGAL::Triangular_expansion_visibility_2<Arrangement_2, CGAL::Tag_true>
// Visibility_2;
// CGAL::test_model_methods<Visibility_2>();
// CGAL::run_tests<Visibility_2>(1);
// }
}
{
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
typedef CGAL::Arr_segment_traits_2<Kernel> Traits_2;
typedef CGAL::Arrangement_2<Traits_2> Arrangement_2;
// {
// typedef CGAL::Triangular_expansion_visibility_2<Arrangement_2, CGAL::Tag_false>
// Visibility_2;
// CGAL::test_model_methods<Visibility_2>();
// CGAL::run_tests<Visibility_2>(1);
// }
// {
// typedef CGAL::Triangular_expansion_visibility_2<Arrangement_2, CGAL::Tag_true>
// Visibility_2;
// CGAL::test_model_methods<Visibility_2>();
// CGAL::run_tests<Visibility_2>(1);
// }
}
return 0;
}