cgal/Map_overlay_2/include/CGAL/Map_overlay_sweep.h

1698 lines
66 KiB
C++

// Copyright (c) 1997 Tel-Aviv University (Israel).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Eti Ezra <estere@post.tau.ac.il>
#ifndef CGAL_MAP_OVERLAY_SWEEP_H
#define CGAL_MAP_OVERLAY_SWEEP_H
#include <CGAL/basic.h>
#include <CGAL/In_place_list.h>
#include <CGAL/Handle.h>
#include <CGAL/assertions.h>
#include <CGAL/Map_overlay_base.h>
#include <CGAL/Sweep_line_2_old/Sweep_curves_base_2.h>
#include <CGAL/Map_overlay_2/Point_handle_plus.h>
#include <vector>
#include <list>
CGAL_BEGIN_NAMESPACE
template <class PM_>
class X_curve_plus_id_handle;
template <class PM_>
class Point_handle_plus;
struct Map_overlay_sweep_utils {
// X_curve_plus_id_handle:
// holds a curve and its id number.
// The addition of id number to a curve was made due to overlapping
// (in which some binary predicates return EQUAL,
// while we are interseted in sharp order relation.
template <class PM_>
class X_curve_plus_id_handle : public PM_::Traits::X_curve
{
public:
typedef PM_ PM;
typedef typename PM::Traits Traits;
//typedef SweepLineTraits_2 Traits;
typedef typename Traits::X_curve curve;
typedef typename Traits::Point Point;
//typedef typename Arrangement::Halfedge_handle Halfedge_handle;
typedef typename PM::Halfedge_const_handle Halfedge_const_handle;
X_curve_plus_id_handle() :
curve(), parent(), first_map_(true), flipped_(false) {};
X_curve_plus_id_handle(const curve &cv, Halfedge_const_handle h,
bool first_map, bool flipped, unsigned int id = 0) :
curve(cv), parent(h), first_map_(first_map), flipped_(flipped), id_(id){}
//Arr_X_curve_plus(Halfedge_handle h, bool b) : curve(h->curve()),
//parent(h), first_map(b) {}
X_curve_plus_id_handle(Halfedge_const_handle h,
bool first_map, bool flipped,
unsigned int id = 0) :
curve(h->curve()), parent(h),
first_map_(first_map), flipped_(flipped), id_(id) {}
// used when no Halfedge_handle is supplied.
X_curve_plus_id_handle(const curve &cv, bool first_map,
bool flipped, unsigned int id = 0) :
curve(cv), parent(), first_map_(first_map),
flipped_(flipped), id_(id) {};
X_curve_plus_id_handle(const X_curve_plus_id_handle &cv) :
curve(cv), parent(cv.parent), first_map_(cv.first_map()),
flipped_(cv.flipped()), id_(cv.id()) {}
~X_curve_plus_id_handle(){}
X_curve_plus_id_handle& operator=(const X_curve_plus_id_handle &cv)
{
curve::operator=(cv);
parent=cv.get_parent();
first_map_ = cv.first_map();
flipped_= cv.flipped();
id_ = cv.id();
return *this;
}
bool operator==(const X_curve_plus_id_handle &cv) const
{
//return curve::operator==(cv);
Traits traits;
return (id_ == cv.id() && traits.curve_equal(*this, cv));
}
void set_id(unsigned int i) { id_ = i; }
Halfedge_const_handle get_parent() const
{
return parent;
}
bool first_map() const { return first_map_; }
bool flipped() const { return flipped_; }
unsigned int id() const { return id_; }
protected:
Halfedge_const_handle parent;
bool first_map_;
bool flipped_;
unsigned int id_;
};
};
template <class PM_,
class Map_overlay_change_notification_>
class Map_overlay_sweep :
public Map_overlay_base<PM_, Map_overlay_change_notification_>,
public Sweep_curves_base_2<typename std::list<
Map_overlay_sweep_utils::X_curve_plus_id_handle<PM_> >::iterator,
typename PM_::Traits, Point_handle_plus<PM_>,
Map_overlay_sweep_utils::X_curve_plus_id_handle<PM_> >
{
public:
typedef PM_ PM;
typedef Map_overlay_change_notification_ Map_overlay_change_notification;
//typedef std::list<typename
//Map_overlay_sweep_utils::X_curve_plus_id_handle<PM> >::iterator
//Curve_iterator;
typedef Point_handle_plus<PM> Point_plus;
typedef Map_overlay_sweep_utils::X_curve_plus_id_handle<PM> X_curve_plus;
typedef typename std::list<X_curve_plus>::iterator Curve_iterator;
typedef typename PM::Vertex_handle Vertex_handle;
typedef typename PM::Halfedge_handle Halfedge_handle;
typedef typename PM::Face_handle Face_handle;
typedef typename PM::Vertex_const_handle Vertex_const_handle;
typedef typename PM::Halfedge_const_handle Halfedge_const_handle;
typedef typename PM::Face_const_handle Face_const_handle;
typedef typename PM::Vertex Vertex;
typedef typename PM::Halfedge Halfedge;
typedef typename PM::Face Face;
typedef typename PM::Vertex_iterator Vertex_iterator;
typedef typename PM::Vertex_const_iterator Vertex_const_iterator;
typedef typename PM::Halfedge_iterator Halfedge_iterator;
typedef typename PM::Halfedge_const_iterator Halfedge_const_iterator;
typedef typename PM::Face_iterator Face_iterator;
typedef typename PM::Face_const_iterator Face_const_iterator;
typedef typename PM::Ccb_halfedge_circulator Ccb_halfedge_circulator;
typedef typename PM::Locate_type Locate_type;
//typedef SweepLineTraits_2 Traits;
typedef typename PM::Traits Traits;
typedef typename Traits::X_curve X_curve;
typedef typename Traits::Point Point;
typedef Sweep_curves_base_2<Curve_iterator, Traits, Point_plus, X_curve_plus>
Base;
typedef typename Base::Curve_node Curve_node;
typedef typename Base::Intersection_point_node Intersection_point_node;
typedef typename Base::Points_iterator Points_iterator;
typedef typename Base::Points_const_iterator Points_const_iterator;
typedef typename Base::Curve_node_iterator Curve_node_iterator;
typedef typename Base::Curve_node_const_iterator Curve_node_const_iterator;
typedef typename Base::X_curve_list X_curve_list;
typedef typename Base::X_curve_list_iterator X_curve_list_iterator;
typedef typename Base::Vertices_points_plus Vertices_points_plus;
typedef typename Base::Event_queue Event_queue;
typedef typename Base::Status_line Status_line;
typedef typename Vertices_points_plus::value_type
Vertices_points_plus_value_type;
typedef typename Event_queue::value_type Event_queue_value_type;
typedef typename Status_line::value_type Status_line_value_type;
typedef typename Vertices_points_plus::iterator
Vertices_points_plus_iterator;
typedef typename Event_queue::iterator Event_queue_iterator;
typedef typename Status_line::iterator Status_line_iterator;
typedef typename std::list<Curve_node>::iterator list_Curve_node_iterator;
typedef std::list<X_curve_plus> X_curve_plus_list;
typedef typename X_curve_plus_list::iterator X_curve_plus_list_iterator;
//typedef Curve_node::Points_iterator Points_iterator; typedef
//Curve_node::Points_const_iterator Points_const_iterator; typedef
//Intersection_point_node::Curve_node_iterator Curve_node_iterator;
//typedef Intersection_point_node::Curve_node_const_iterator
//Curve_node_const_iterator;
// typedef std::pair<Curve_node, X_curve_plus> Curve_pair;
// typedef std::map<Point, Point_plus, less_xy<Point> >
// Vertices_points_plus; typedef std::multimap<Point,
// Intersection_point_node, less_xy<Point> > Event_queue;
// typedef std::multimap<Curve_node, X_curve_plus,
// less_yx<Curve_node> > Status_line;
void map_overlay(const PM &a1,
const PM &a2,
Map_overlay_change_notification *pm_change_notf,
PM &result)
{
std::list<X_curve_plus> curves;
unsigned int id = 0;
// updating curevs to contain all updated curves plus.
Halfedge_const_iterator h_iter;
for (h_iter = a1.halfedges_begin();
h_iter != a1.halfedges_end(); ++h_iter, ++h_iter, ++id){
bool b;
X_curve cv(h_iter->curve());
if ((b = is_right(traits->curve_source(h_iter->curve()),
traits->curve_target(h_iter->curve())) ))
cv = traits->curve_opposite(h_iter->curve());
Halfedge_const_handle h = h_iter;
curves.push_back(X_curve_plus(cv, h, true, b, id));
//is_right(traits.curve_source(cv),
// traits.curve_target(cv))) );
}
for(h_iter = a2.halfedges_begin();
h_iter != a2.halfedges_end(); ++h_iter, ++h_iter, ++id){
bool b;
X_curve cv(h_iter->curve());
if ((b = is_right(traits->curve_source(h_iter->curve()),
traits->curve_target(h_iter->curve())) ))
cv = traits->curve_opposite(h_iter->curve());
Halfedge_const_handle h = h_iter;
curves.push_back(X_curve_plus(cv, h, false, b, id));
//is_right(traits.curve_source(cv),
// traits.curve_target(cv))) );
}
sweep_curves_to_planar_map(curves.begin(),
curves.end(),
pm_change_notf,
result);
pm_change_notf->update_all_faces(result);
}
private:
void sweep_curves_to_planar_map(Curve_iterator curves_begin,
Curve_iterator curves_end,
Map_overlay_change_notification
*pm_change_notf,
PM &result)
{
//Traits traits;
typename Base::Less_xy event_queue_pred(traits);
Event_queue event_queue(event_queue_pred);
typename Base::Less_yx status_pred(traits);
Status_line status(status_pred);
//Event_queue event_queue;
//Status_line status;
//int c_sweep_t;
//c_sweep_t = clock();
#ifdef CGAL_SWEEP_LINE_DEBUG
unsigned int n = 0;
for (Curve_iterator cv_iter = curves_begin;
cv_iter != curves_end; ++cv_iter, ++n);
cout<<"number of edges on input "<< n <<std::endl;
#endif
/*
// now adding to the x-monotone container all the curves
// in the original subdivision.
for (X_curve_list_iterator cv_iter = subdivision_curves.begin();
cv_iter != subdivision_curves.end(); ++cv_iter)
x_monotone_curves.push_back(*cv_iter);*/
typename Base::Less_xy pred(traits);
Vertices_points_plus input_vertices(pred);
for (Curve_iterator cv_iter = curves_begin;
cv_iter != curves_end; ++cv_iter){
if (input_vertices.find(traits->curve_source(*cv_iter)) ==
input_vertices.end())
input_vertices.insert( Vertices_points_plus_value_type
(traits->curve_source(*cv_iter),
Point_plus(traits->curve_source(*cv_iter))) );
if (input_vertices.find(traits->curve_target(*cv_iter)) ==
input_vertices.end())
input_vertices.insert( Vertices_points_plus_value_type
(traits->curve_target(*cv_iter),
Point_plus(traits->curve_target(*cv_iter))) );
}
// end of input_vertices construction.
// now creating the Curve_node handles and the event queue.
for(Curve_iterator cv_iter = curves_begin;
cv_iter != curves_end; ++cv_iter){
//X_curve cv(*cv_iter);
//if (is_right(traits.curve_source(*cv_iter),
// traits.curve_target(*cv_iter)) )
// cv = traits.curve_opposite(*cv_iter);
#ifdef CGAL_SWEEP_LINE_DEBUG
cout<< *cv_iter <<std::endl;
#endif
Vertices_points_plus_iterator curr_point_plus =
input_vertices.find( traits->curve_source(*cv_iter) );
//assert(traits.curve_source(cv) == curr_point_plus->second.point());
Event_queue_iterator edge_point =
event_queue.find( traits->curve_source(*cv_iter) );
// defining one cv_node for both source and target event points.
//X_curve_plus cv_plus(cv, id); // to satisfy BCC.
Curve_node cv_node = Curve_node(*cv_iter,
curr_point_plus->second,traits );
Intersection_point_node source_point_node =
Intersection_point_node(cv_node, curr_point_plus->second,traits );
if (edge_point == event_queue.end() ||
edge_point->second.get_point() != source_point_node.get_point())
event_queue.insert(Event_queue_value_type
(traits->curve_source(*cv_iter),
source_point_node));
else
edge_point->second.merge(source_point_node);
edge_point = event_queue.find( traits->curve_target(*cv_iter) );
curr_point_plus = input_vertices.find( traits->curve_target(*cv_iter) );
//assert(traits.curve_target(cv) == curr_point_plus->second.point());
Intersection_point_node target_point_node =
Intersection_point_node(cv_node, curr_point_plus->second, traits );
if (edge_point == event_queue.end() ||
edge_point->second.get_point() != target_point_node.get_point())
event_queue.insert(Event_queue_value_type(traits->
curve_target(*cv_iter),
target_point_node));
else
edge_point->second.merge(target_point_node);
}
// now starting the sweeping.
unsigned int queue_size = 0;
bool event_terminated = true;
//bool event_overlap_terminated = true;
while ( !(event_queue.empty()) ){
++queue_size;
// fetch the next event.
Event_queue_iterator event = event_queue.begin();
const Point& event_point = event->first;
Intersection_point_node& point_node = event->second;
//bool event_terminated = true;
#ifdef CGAL_SWEEP_LINE_DEBUG
cout<<"* * * event point is "<<event_point<<
" and point node is "<<point_node.get_point().point()<<std::endl;
CGAL_assertion(event_point == point_node.get_point().point());
#endif
// reinitializing event_terminated to true only after the updating of
// the subdivision.
event_terminated = true;
// now continue with the sweep line.
event_terminated = handle_one_event (event_queue, status,
event_point, point_node);
// handling overlapping curves.
// On each overlapping group, we remove iteratively each curve and check
// for new events after the removing.
// when finish, we reinsert to the status all the overlappting removed
// curves.
handle_overlapping_curves(event_queue, status, event_point, point_node);
if (!event_terminated){
handle_one_event (event_queue, status, event_point, point_node);
}
#ifdef CGAL_SWEEP_LINE_DEBUG
cout<<"Printing status line "<<std::endl;
print_status(status);
#endif
for (Curve_node_iterator cv_iter = point_node.curves_begin();
cv_iter != point_node.curves_end(); ++cv_iter){
if (event_point != traits->curve_source(cv_iter->get_curve()) &&
event_point == cv_iter->get_rightmost_point().point())
cv_iter->erase_rightmost_point();
}
// now, updating the planar map (or arrangement) according the curves
// enemating from the currnet event point.
update_subdivision(point_node, pm_change_notf, result);
// updating all the new intersection nodes of the curves
// participating within the event.
for (Curve_node_iterator cv_iter = point_node.curves_begin();
cv_iter != point_node.curves_end(); ++cv_iter){
if (event_point != cv_iter->get_rightmost_point().point())
cv_iter->push_event_point(point_node.get_point());
}
//if (event_terminated)
event_queue.erase(event);
}
#ifdef CGAL_SWEEP_LINE_DEBUG
std::cout<<"the number of events was "<<queue_size<<std::endl;
#endif
CGAL_expensive_postcondition_code(is_valid(status));
//c_sweep_t = clock() - c_sweep_t;
//std::cout<<"The time required by sweep proccess: "<< (double) c_sweep_t /
//(double) CLOCKS_PER_SEC<<std::endl;
}
// void sweep_curves_to_planar_map(Curve_iterator curves_begin,
// Curve_iterator curves_end,
// Map_overlay_change_notification
// *pm_change_notf,
// PM &result)
// {
// Traits traits;
// Event_queue event_queue;
// Status_line status;
// Vertices_points_plus input_vertices;
// #ifdef CGAL_SWEEP_LINE_DEBUG
// unsigned int n = 0;
// for (Curve_iterator cv_iter = curves_begin;
// cv_iter != curves_end; ++cv_iter, ++n);
// cout<<"number of edges on input "<< n <<std::endl;
// #endif
// /*
// // first handling the case of which results is not empty: since we are
// sweeping the curves we have to take all
// //the curves of result and 'paste' it to the input curves, then we have
// to clear result.
// X_curve_plus_list subdivision_curves;
// for (Halfedge_iterator h_iter = result.halfedges_begin();
// h_iter != result.halfedges_end(); h_iter++, h_iter++)
// subdivision_curves.push_back(h_iter->curve());
// result.clear();
// // Now, creating all the point_plus handle: for any pair of overlapping
// points from the input we ensure we have only one handle. - not having
// such a structure as input_vertices caused a bug.
// Vertices_points_plus input_vertices;
// for (X_curve_list_iterator cv_iter = subdivision_curves.begin();
// cv_iter != subdivision_curves.end(); cv_iter++){
// if (input_vertices.find(traits.curve_source(*cv_iter)) ==
// input_vertices.end())
// input_vertices.insert(Vertices_points_plus_value_type
// (traits.curve_source(*cv_iter),
// Point_plus(traits.curve_source(*cv_iter))) );
// if (input_vertices.find(traits.curve_target(*cv_iter)) ==
// input_vertices.end())
// input_vertices.insert(Vertices_points_plus_value_type
// (traits.curve_target(*cv_iter),
// Point_plus(traits.curve_target(*cv_iter))) );
// }*/
// // splitting all curves to x-monotone curves.
// X_curve_plus_list x_monotone_curves;
// for (Curve_iterator cv_iter = curves_begin;
// cv_iter != curves_end; ++cv_iter){
// /*if (!traits.is_x_monotone(*cv_iter)) {
// X_curve_list x_monotone_subcurves;
// traits.curve_make_x_monotone(*cv_iter, x_monotone_subcurves);
// #ifdef CGAL_SWEEP_LINE_DEBUG
// std::cout<<"printing x-monotone parts"<<std::endl;
// #endif
// for(X_curve_list_iterator iter = x_monotone_subcurves.begin();
// iter != x_monotone_subcurves.end(); iter++){
// #ifdef CGAL_SWEEP_LINE_DEBUG
// std::cout<<*iter<<endl;
// #endif
// x_monotone_curves.push_back(X_curve_plus(*iter, cv_iter->parent(),
// cv_iter->first_map(), cv_iter->id()));
// }
// }
// else*/
// x_monotone_curves.push_back(*cv_iter);
// }
// /*
// // now adding to the x-monotone container all the curves
// // in the original subdivision.
// for (X_curve_plus_list_iterator cv_iter = subdivision_curves.begin();
// cv_iter != subdivision_curves.end(); cv_iter++)
// x_monotone_curves.push_back(*cv_iter);*/
// // Now, creating all the point_plus handle: for any pair of
// overlapping points
// // from the input we ensure we have only one handle. - not having such
// // a structure as input_vertices caused a bug.
// for (X_curve_plus_list_iterator cv_iter = x_monotone_curves.begin();
// cv_iter != x_monotone_curves.end(); ++cv_iter){
// if (input_vertices.find(traits.curve_source(*cv_iter)) ==
// input_vertices.end())
// input_vertices.insert( Vertices_points_plus_value_type
// (traits.curve_source(*cv_iter),
// Point_plus(traits.curve_source(*cv_iter))));
// if (input_vertices.find(traits.curve_target(*cv_iter)) ==
// input_vertices.end())
// input_vertices.insert( Vertices_points_plus_value_type
// (traits.curve_target(*cv_iter),
// Point_plus(traits.curve_target(*cv_iter))));
// }
// // end of input_vertices construction.
// // now creating the Curve_node handles and the event queue.
// unsigned int id = 0;
// for(X_curve_plus_list_iterator cv_iter = x_monotone_curves.begin();
// cv_iter != x_monotone_curves.end(); ++cv_iter, ++id){
// X_curve cv(*cv_iter);
// //Halfedge_const_handle parent = cv_iter->get_parent();
// if (is_right(traits.curve_source(*cv_iter),
// traits.curve_target(*cv_iter)) )
// cv = traits.curve_opposite(*cv_iter);
// #ifdef CGAL_SWEEP_LINE_DEBUG
// cout<<cv<<std::endl;
// #endif
// Vertices_points_plus_iterator curr_point_plus =
// input_vertices.find( traits.curve_source(cv) );
// //assert(traits.curve_source(cv) == curr_point_plus->second.point());
// Event_queue_iterator edge_point =
// event_queue.find( traits.curve_source(cv) );
// // defining one cv_node for both source and target event points.
// //X_curve_plus cv_plus(cv, id); // to satisfy BCC.
// Curve_node cv_node = Curve_node(X_curve_plus(cv,
// cv_iter->get_parent(),
// cv_iter->first_map(),
// cv_iter->flipped(),
// id),
// curr_point_plus->second);
// Intersection_point_node source_point_node =
// Intersection_point_node(cv_node, curr_point_plus->second );
// if (edge_point == event_queue.end() ||
// edge_point->second.get_point() != source_point_node.get_point())
// event_queue.insert(Event_queue_value_type
// (traits.curve_source(cv),
// source_point_node));
// else
// edge_point->second.merge(source_point_node);
// edge_point = event_queue.find( traits.curve_target(cv) );
// curr_point_plus = input_vertices.find( traits.curve_target(cv) );
// //assert(traits.curve_target(cv) == curr_point_plus->second.point());
// Intersection_point_node target_point_node =
// Intersection_point_node(cv_node, curr_point_plus->second );
// if (edge_point == event_queue.end() ||
// edge_point->second.get_point() != target_point_node.get_point())
// event_queue.insert(Event_queue_value_type(traits.curve_target(cv),
// target_point_node));
// else
// edge_point->second.merge(target_point_node);
// }
// int c_sweep_t;
// c_sweep_t = clock();
// // now starting the sweeping.
// unsigned int queue_size = 0;
// bool event_terminated = true;
// //bool event_overlap_terminated = true;
// while ( !(event_queue.empty()) ){
// queue_size++;
// // fetch the next event.
// Event_queue_iterator event = event_queue.begin();
// const Point& event_point = event->first;
// Intersection_point_node& point_node = event->second;
// //bool event_terminated = true;
// #ifdef CGAL_SWEEP_LINE_DEBUG
// cout<<"* * * event point is "<<event_point<<
// " and point node is "<<point_node.get_point().point()<<std::endl;
// CGAL_assertion(event_point == point_node.get_point().point());
// #endif
// event_terminated = true; // reinitializing event_terminated to true
// only after the updating of the subdivision.
// // now continue with the sweep line.
// event_terminated = handle_one_event (event_queue, status,
// event_point, point_node);
// // handling overlapping curves.
// // On each overlapping group, we remove iteratively each curve and
// // check for new events after the removing.
// // when finish, we reinsert to the status all the overlappting
// removed curves.
// handle_overlapping_curves(event_queue, status, event_point,
// point_node);
// if (!event_terminated){
// handle_one_event (event_queue, status, event_point, point_node);
// }
// #ifdef CGAL_SWEEP_LINE_DEBUG
// cout<<"Printing status line "<<std::endl;
// print_status(status);
// #endif
// for (Curve_node_iterator cv_iter = point_node.curves_begin();
// cv_iter != point_node.curves_end(); ++cv_iter){
// if (event_point != traits.curve_source(cv_iter->get_curve()) &&
// event_point == cv_iter->get_rightmost_point().point())
// cv_iter->erase_rightmost_point();
// }
// // now, updating the planar map (or arrangement) according the curves
// // enemating from the currnet event point.
// update_subdivision(point_node, pm_change_notf, result);
// // updating all the new intersection nodes of the curves
// // participating within the event.
// for (Curve_node_iterator cv_iter = point_node.curves_begin();
// cv_iter != point_node.curves_end(); ++cv_iter){
// if (event_point != cv_iter->get_rightmost_point().point())
// cv_iter->push_event_point(point_node.get_point());
// }
// //if (event_terminated)
// event_queue.erase(event);
// }
// #ifdef CGAL_SWEEP_LINE_DEBUG
// std::cout<<"the number of events was "<<queue_size<<std::endl;
// #endif
// CGAL_expensive_postcondition_code(is_valid(status));
// c_sweep_t = clock() - c_sweep_t;
// std::cout<<"The time required by sweep proccess: "
// << (double) c_sweep_t / (double) CLOCKS_PER_SEC<<std::endl;
// }
/* bool check_status_neighbors_intersections(Event_queue &event_queue,
// Status_line& status, Status_line::iterator lower_neighbor,
// Point& point)
{
#ifdef CGAL_SWEEP_LINE_DEBUG
cout<<"Printing status line "<<std::endl;
print_status(status);
#endif
Traits traits;
//for (Status_line::iterator status_iter = status.begin();
//status_iter != status.end(); status_iter++)
Curve_node cv1 = lower_neighbor->first;
Status_line::iterator next_neighbor = ++lower_neighbor;
if (next_neighbor == status.end())
return false;
lower_neighbor--;
Curve_node cv2 = next_neighbor->first;
#ifdef CGAL_SWEEP_LINE_DEBUG
cout<<"cv1 and cv2 are "<<cv1.get_curve()<<" "<<cv2.get_curve()<<std::endl;
#endif
// in each node - checking intersections between two adjacent curves and
// updating the event queue if needed.
Point xp1, xp2;
Point ref_point(lower_neighbor->first.get_rightmost_point().point());
if (is_left(next_neighbor->first.get_rightmost_point().point(),
// lower_neighbor->first.get_rightmost_point().point()))
ref_point = next_neighbor->first.get_rightmost_point().point();
if (traits.nearest_intersection_to_right (cv1.get_curve(), cv2.get_curve(),
// ref_point, xp1, xp2) ){
// we choose the leftmost point because the intersection point may be one
// of the points on lower_neighbor or next_neighbor, specially it can be a
// tangent point, and the function nearest_intersection_to_right may
// return false (it's third parameter is the ittersection point itself!).
#ifdef CGAL_SWEEP_LINE_DEBUG
cout<<"rightmost pointon status, xp1 and xp2 are "
<<lower_neighbor->first.get_rightmost_point().point()<<" "<<xp1<<" "
<<xp2<<std::endl;
#endif
// have to handle overlapping.
if (xp1 == lower_neighbor->first.get_rightmost_point().point())
xp1 = xp2;
// for debugging.
//if (traits.curve_compare_y_at_x(cv1.get_curve(), xp1) !=
// Traits::ON_CURVE)
// cout<<"The point "<<xp1<<" is not on the curve "
// <<cv1.get_curve()<<std::endl;
//if (traits.curve_compare_y_at_x(cv2.get_curve(),
// xp1) != Traits::ON_CURVE)
// cout<<"The point "<<xp1<<" is not on the curve "<<cv2.get_curve()
// <<std::endl;
// end debugging.
// if cv1 and cv2 have common edge point - we do not consider it as an
// intersection point.
if ( !( (xp1 == traits.curve_source(cv1.get_curve()) ||
xp1 == traits.curve_target(cv1.get_curve()) )
&&
(xp1 == traits.curve_source(cv2.get_curve()) ||
xp1 == traits.curve_target(cv2.get_curve()) )) ){
//status_iter->first.push_event_point(xp1);
//next_iter->first.push_event_point(xp1);
Event_queue::iterator xp_event = event_queue.find(xp1);
bool xp_cv1_in_queue = false, xp_cv2_in_queue = false;
if (xp_event == event_queue.end())
event_queue.insert(Event_queue::value_type(xp1,
Intersection_point_node(cv1, cv2, xp1)));
else{
// have to check the event is a new event. (we might calculated with
// point before).
for ( Curve_node_iterator cv_iter = xp_event->second.curves_begin();
cv_iter != xp_event->second.curves_end(); cv_iter++){
if (traits.curve_equal(cv_iter->get_curve(), cv1.get_curve()) )
// fix later : change it to compare the curve nodes it self!
xp_cv1_in_queue = true;
if (traits.curve_equal(cv_iter->get_curve(), cv2.get_curve()) )
xp_cv2_in_queue = true;
}
if (!xp_cv1_in_queue && !xp_cv2_in_queue)
xp_event->second.merge(Intersection_point_node(cv1, cv2,
Point_plus(xp1)));
else if (!xp_cv1_in_queue)
xp_event->second.merge(Intersection_point_node(cv1,
Point_plus(xp1)));
else if (!xp_cv2_in_queue)
xp_event->second.merge(Intersection_point_node(cv2,
Point_plus(xp1)));
}
// updating the curve_node holding the right point of cv1 (so when we
// get to this event point
//we can find easily the curve node and remove it from status.
point = xp1;
return (!xp_cv1_in_queue || !xp_cv2_in_queue);
}
}
return false;
}*/
void update_subdivision(Intersection_point_node& point_node,
Map_overlay_change_notification *pm_change_notf,
PM &pm)
{
#ifdef CGAL_SWEEP_LINE_DEBUG
cout<<"--------- updating map with point node"<<
point_node.get_point().point() <<std::endl;
for (Curve_node_iterator cv_iter1= point_node.curves_begin();
cv_iter1 != point_node.curves_end(); cv_iter1++){
cv_iter1++;
Curve_node_iterator cv_iter2 = cv_iter1;
cv_iter1--;
for ( ; cv_iter2 != point_node.curves_end(); cv_iter2++){
if (traits->curves_overlap(cv_iter1->get_curve(),
cv_iter2->get_curve()))
cout<<"update_subdivision "<<cv_iter1->get_curve()<<
" and "<< cv_iter2->get_curve() <<" are overlapping"<<endl;
}
}
#endif
X_curve prev_sub_cv;
for (Curve_node_iterator cv_iter = point_node.curves_begin();
cv_iter != point_node.curves_end(); ++cv_iter){
#ifdef CGAL_SWEEP_LINE_DEBUG
cout<<"now handling "<<cv_iter->get_curve()<<endl;
#endif
bool overlap=false;
if (is_left(cv_iter->get_rightmost_point().point(),
point_node.get_point().point())) {
// means we have a new sub curve to insert.
Halfedge_handle h;
// first splitting the curve in the points
// cv_iter->get_rightmost_point().point()
// and point_node.get_point().point().
X_curve cv = cv_iter->get_curve(), sub_cv = cv_iter->get_curve(),
right_cv = cv;
//cout<<"cv is "<<cv<<endl;
if (traits->curve_source(cv) !=
cv_iter->get_rightmost_point().point() &&
traits->curve_target(cv) !=
cv_iter->get_rightmost_point().point() ) {
traits->curve_split(cv, sub_cv, right_cv,
cv_iter->get_rightmost_point().point());
cv = right_cv;
}
if (traits->curve_source(cv) != point_node.get_point().point() &&
traits->curve_target(cv) != point_node.get_point().point())
traits->curve_split(cv, sub_cv, right_cv,
point_node.get_point().point());
else
sub_cv = right_cv;
// for debugging!
//assert(sub_cv == X_curve(cv_iter->get_rightmost_point().point(),
// point_node.get_point().point()));
//cout<<"sub curve calculates is "<<endl;
//cout<<sub_cv<<endl;
//cout<<"And the right curve is supposed to be"<<endl;
//cout<<X_curve (cv_iter->get_rightmost_point().point(),
// point_node.get_point().point())<<endl;
if (cv_iter != point_node.curves_begin()){
if (traits->curves_overlap(sub_cv, prev_sub_cv)){
//cout<<sub_cv<<" and "<< prev_sub_cv<<" are overlapping"<<endl;
overlap=true;
}
}
#ifdef CGAL_SWEEP_LINE_DEBUG
cout<<"inserting "<<sub_cv<<endl;
#endif
if (cv_iter->get_curve().flipped()){
//cout<<"update subdivision: curve is flipped "<<sub_cv<<endl;
sub_cv = traits->curve_opposite(sub_cv);
//cout<<sub_cv<<endl;
}
if (pm_change_notf)
pm_change_notf->
set_curve_attributes(sub_cv, cv_iter->get_curve().get_parent(),
cv_iter->get_curve().first_map());
if (overlap){
// special case of overlapping:
// We do not insert the overlapped curve.
// However, we have to call add_edge of the notifier in order to
// update attributes
// of the current halfedge.
if (pm_change_notf){
h = find_halfedge(sub_cv, pm);
pm_change_notf->add_edge(sub_cv, h, true, true);
}
}
else {
prev_sub_cv = sub_cv;
if (cv_iter->get_rightmost_point().vertex() != Vertex_handle(NULL)){
//assert(cv_iter->get_rightmost_point().point() ==
// cv_iter->get_rightmost_point().vertex()->point());
if (point_node.get_point().vertex() != Vertex_handle(NULL)) {
//assert(point_node.get_point().point() ==
// point_node.get_point().vertex()->point());
if (cv_iter->get_curve().flipped()) // opposite orientation.
h = pm.insert_at_vertices(sub_cv,
point_node.get_point().vertex(),
cv_iter->
get_rightmost_point().vertex(),
pm_change_notf);
else
h = pm.insert_at_vertices(sub_cv,
cv_iter->
get_rightmost_point().vertex(),
point_node.get_point().vertex(),
pm_change_notf);
}
else {
if (cv_iter->get_curve().flipped())
h = pm.insert_from_vertex (sub_cv,
cv_iter->
get_rightmost_point().vertex(),
false,
pm_change_notf);
else
h = pm.insert_from_vertex (sub_cv,
cv_iter->
get_rightmost_point().vertex(),
true,
pm_change_notf);
}
}
else if (point_node.get_point().vertex() != Vertex_handle(NULL)) {
//assert(point_node.get_point().point()
// == point_node.get_point().vertex()->point());
if (cv_iter->get_curve().flipped())
h = pm.insert_from_vertex (sub_cv,
point_node.get_point().vertex(),
true,
pm_change_notf);
else
h = pm.insert_from_vertex (sub_cv,
point_node.get_point().vertex(),
false,
pm_change_notf);
}
else{
h = pm.insert_in_face_interior (sub_cv,
pm.unbounded_face(),
pm_change_notf);
// the point is that if the curve has no source to start the
// insertion from, it has to be inserted to the unbounded face,
// because all the curves to the right of it have not inserted yet,
// and in that stage of the sweep line, the curve is on the
// unbounded face - later on it will be updated automatically by
// the Planar map (Arrangement) insert functions.
}
}
//assert(h->source()->point() == cv_iter->get_rightmost_point().point()
// ||
// (h->target()->point() == cv_iter->get_rightmost_point().point()));
// now update the vertex handle of each point.
//if (cv_iter->get_rightmost_point().vertex() == Vertex_handle(NULL))
if (!overlap || pm_change_notf){
if (h->source()->point() ==
cv_iter->get_rightmost_point().point())
//cv_iter->set_vertex_of_rightmost_point(h->source());
cv_iter->get_rightmost_point().set_vertex(h->source());
else if (h->target()->point() ==
cv_iter->get_rightmost_point().point())
//cv_iter->set_vertex_of_rightmost_point(h->target());
cv_iter->get_rightmost_point().set_vertex(h->target());
}
//assert(h->source()->point() == point_node.get_point().point() ||
// (h->target()->point() == point_node.get_point().point()));
//if (point_node.get_point().vertex() == Vertex_handle(NULL))
if (!overlap || pm_change_notf){
if (h->source()->point() ==
point_node.get_point().point())
point_node.get_point().set_vertex(h->source());
else if (h->target()->point() ==
point_node.get_point().point())
point_node.get_point().set_vertex(h->target());
}
}
// else - no new sub curve is inserted to the subdivision.
}
}
Halfedge_handle find_halfedge(const X_curve& cv, PM& pm)
{
//cout<<"In find_halfedge"<<endl;
Locate_type lt;
Halfedge_handle h = pm.locate(traits->curve_source(cv),lt);
//cout<<"cv="<<cv<<endl;
//cout<<"h->curve()="<<h->curve()<<endl;
//if (h->curve() == cv || h->curve() == traits.curve_opposite(cv))
// return h;
if (traits->curve_equal(h->curve(),cv) ||
traits->curve_equal(h->curve(),traits->curve_opposite(cv)) )
return h;
Vertex_handle v;
if (h->source()->point() == traits->curve_source(cv))
v = h->source();
else
v = h->target();
typename PM::Halfedge_around_vertex_circulator
circ = v->incident_halfedges();
do {
//cout<<"circ->curve()="<<circ->curve()<<endl;
if (traits->curve_equal(circ->curve(),cv) ||
traits->curve_equal(circ->curve(),traits->curve_opposite(cv)))
return Halfedge_handle(circ);
//if (circ->curve() == cv || circ->curve() == traits.curve_opposite(cv))
// return Halfedge_handle(circ);
} while (++circ != v->incident_halfedges());
CGAL_assertion(0);
return Halfedge_handle(0);
}
/* void update_subdivision(Intersection_point_node& point_node,
Map_overlay_change_notification *pm_change_notf,
PM &pm)
{
for (Curve_node_iterator cv_iter = point_node.curves_begin();
cv_iter != point_node.curves_end(); cv_iter++){
if (is_left(cv_iter->get_rightmost_point().point(),
point_node.get_point().point())) { // means we have a new sub curve to
insert.
Halfedge_handle h;
pm_change_notf->set_curve_attributes(X_curve(cv_iter->
get_rightmost_point().point(), point_node.get_point().point()),
cv_iter->
get_curve().get_parent(),
cv_iter->
get_curve().get_parent()->twin(),
cv_iter->
get_curve().first_map());
if (cv_iter->get_rightmost_point().vertex() != Vertex_handle(NULL)){
//assert(cv_iter->get_rightmost_point().point() ==
//cv_iter->get_rightmost_point().vertex()->point());
if (point_node.get_point().vertex() != Vertex_handle(NULL)) {
//assert(point_node.get_point().point() ==
//point_node.get_point().vertex()->point());
h = pm.insert_at_vertices(X_curve( cv_iter->
get_rightmost_point().point(), point_node.get_point().point()),
cv_iter->get_rightmost_point().vertex(),
point_node.get_point().vertex(),
pm_change_notf);
}
else
h = pm.insert_from_vertex (X_curve( cv_iter->
get_rightmost_point().point(), point_node.get_point().point()),
cv_iter->get_rightmost_point().vertex(),
true, pm_change_notf);
}
else if (point_node.get_point().vertex() != Vertex_handle(NULL)) {
//assert(point_node.get_point().point() ==
//point_node.get_point().vertex()->point());
h = pm.insert_from_vertex (X_curve( point_node.get_point().point(), c
v_iter->get_rightmost_point().point()),
point_node.get_point().vertex(),
true, pm_change_notf);
}
else{
h = pm.insert_in_face_interior (X_curve( cv_iter->
get_rightmost_point().point(), point_node.get_point().point()),
pm.unbounded_face(),
pm_change_notf);
// the point is that if the curve has no source to start the insertion
// from, it has to be inserted to the unbounded face, because all the
// curves to the right of it have not inserted yet, and in that stage of
// the sweep line, the curve is on the unbounded face - later on it will
// be updated automatically by the Planar map (Arrangement) insert
// functions.
}
//assert(h->source()->point() == cv_iter->get_rightmost_point().point()
// || (h->target()->point() == cv_iter->get_rightmost_point().point()));
// now update the vertex handle of each point.
//if (cv_iter->get_rightmost_point().vertex() == Vertex_handle(NULL))
{
if (h->source()->point() == cv_iter->get_rightmost_point().point())
cv_iter->set_vertex_of_rightmost_point(h->source());
else if (h->target()->point() ==
cv_iter->get_rightmost_point().point())
cv_iter->set_vertex_of_rightmost_point(h->target());
}
//assert(h->source()->point() == point_node.get_point().point() ||
(h->target()->point() == point_node.get_point().point()));
//if (point_node.get_point().vertex() == Vertex_handle(NULL))
{
if (h->source()->point() == point_node.get_point().point())
point_node.set_vertex(h->source());
else if (h->target()->point() == point_node.get_point().point())
point_node.set_vertex(h->target());
}
}
// else - no new sub curve is inserted to the subdivision.
}
}*/
void update_subdivision_debug(Intersection_point_node& point_node, PM &arr)
{
cout<<"--------- updating map"<<std::endl;
for (Curve_node_iterator cv_iter = point_node.curves_begin();
cv_iter != point_node.curves_end(); cv_iter++)
{
// means we have a new sub curve to insert.
if (is_left(cv_iter->get_rightmost_point().point(),
point_node.get_point().point()))
{
Halfedge_handle h;
cout << "handling curves "<<cv_iter->get_curve()
<< "with right most point so far "
<< cv_iter->get_rightmost_point().point()<<std::endl;
if (cv_iter->get_rightmost_point().vertex() != Vertex_handle(NULL)){
assert(cv_iter->get_rightmost_point().point() ==
cv_iter->get_rightmost_point().vertex()->point());
std::cout << "Point of cv_iter is on map"
<< cv_iter->get_rightmost_point().point() <<std::endl;
if (point_node.get_point().vertex() != Vertex_handle(NULL)) {
std::cout << "And Point of point_node is on map"
<< point_node.get_point().point() <<std::endl;
assert(point_node.get_point().point() ==
point_node.get_point().vertex()->point());
h = arr.insert_at_vertices(X_curve(cv_iter->
get_rightmost_point().point(),
point_node.get_point().point()),
cv_iter->get_rightmost_point().vertex(),
point_node.get_point().vertex());
}
else
h = arr.insert_from_vertex (X_curve(cv_iter->
get_rightmost_point().point(),
point_node.get_point().point()),
cv_iter->get_rightmost_point().vertex(),
true);
}
else if (point_node.get_point().vertex() != Vertex_handle(NULL)) {
std::cout << "Only Point of point_node is on map"
<< point_node.get_point().point() <<std::endl;
assert(point_node.get_point().point() ==
point_node.get_point().vertex()->point());
h = arr.insert_from_vertex (X_curve( point_node.get_point().point(),
cv_iter->
get_rightmost_point().point()),
point_node.get_point().vertex(), true);
}
else{
// debugging.
Locate_type lt;
Halfedge_handle tmp_h = arr.locate(cv_iter->
get_rightmost_point().point(),
lt);
std::cout << "curve right most point locate type is " <<lt
<< ", Point is "<<cv_iter->get_rightmost_point().point()
<< std::endl;
tmp_h = arr.locate(point_node.get_point().point(), lt);
std::cout << "point intersection node locate type is " <<lt
<< ", Point is "<<point_node.get_point().point()<<std::endl;
//assert(lt == Arrangement::UNBOUNDED_FACE);
// end debugging.
h =
arr.insert_in_face_interior(X_curve(cv_iter->
get_rightmost_point().point(),
point_node.get_point().point()),
arr.unbounded_face());
// the point is that if the curve has no source to start the insertion
// from, it has to be inserted to the unbounded face, because all the
// curves to the right of it have not inserted yet, and in that stage
// of the sweep line, the curve is on the unbounded face - later on it
// will be updated automatically by the Planar map (Arrangement)
// insert functions.
}
assert(h->source()->point() == cv_iter->get_rightmost_point().point() ||
(h->target()->point() ==
cv_iter->get_rightmost_point().point()));
// now update the vertex handle of each point.
//if (cv_iter->get_rightmost_point().vertex() == Vertex_handle(NULL))
//for (Curve_node_iterator curr_cv_iter = point_node.curves_begin();
// curr_cv_iter != point_node.curves_end(); curr_cv_iter++)
{
if (h->source()->point() == cv_iter->get_rightmost_point().point())
cv_iter->set_vertex_of_rightmost_point(h->source());
else if (h->target()->point() ==
cv_iter->get_rightmost_point().point())
cv_iter->set_vertex_of_rightmost_point(h->target());
else
assert(0);
}
assert(h->source()->point() == point_node.get_point().point() ||
(h->target()->point() == point_node.get_point().point()));
//if (point_node.get_point().vertex() == Vertex_handle(NULL))
{
if (h->source()->point() == point_node.get_point().point())
point_node.set_vertex(h->source());
else if (h->target()->point() == point_node.get_point().point())
point_node.set_vertex(h->target());
else
assert(0);
}
}
// else - no new sub curve is inserted to the subdivision.
}
// checking that the handles were correctly updated.
for (Curve_node_iterator cv_iter = point_node.curves_begin();
cv_iter != point_node.curves_end(); cv_iter++){
if (is_left(cv_iter->get_rightmost_point().point(),
point_node.get_point().point()))
// means we have a new sub curve to insert.
assert (cv_iter->get_rightmost_point().vertex() != Vertex_handle(NULL));
}
cout<<"--------- finish updating map"<<std::endl;
}
/*
void build_overlay_subdivision(const std::list<Curve_node>& curves,
Map_overlay_change_notification *pmwx_change_notf, Arrangement &arr)
{
#ifdef CGAL_SWEEP_LINE_DEBUG
cout<<"Inserting "<<curves.size()<<" Curve nodes"<<std::endl;
#endif
for (std::list<Curve_node>::const_iterator cv_iter = curves.begin();
cv_iter != curves.end(); cv_iter++){
#ifdef CGAL_SWEEP_LINE_DEBUG
cout<<"The Curve is "<<cv_iter->get_curve()<<std::endl;
#endif
X_curve cv = cv_iter->get_curve(), left_cv, right_cv =
cv_iter->get_curve();
for (Curve_node::Points_const_iterator points_iter =
cv_iter->points_begin(); points_iter != cv_iter->points_end();
points_iter++){
// make surve the splitting is not at the edge points.
if (points_iter == cv_iter->points_begin())
continue;
++points_iter;
if (points_iter == cv_iter->points_end())
break;
points_iter--;
#ifdef CGAL_SWEEP_LINE_DEBUG
cout<<"Right sub curve is "<<right_cv<<"the splitting point is"
<< *points_iter<<std::endl;
#endif
// debugging.
if (traits.curve_compare_y_at_x(cv, *points_iter) !=
Traits::ON_CURVE){
cout<<"The point "<<*points_iter<<" is not on the curve "<<cv
<<std::endl;
break;
}
traits.curve_split(cv, left_cv, right_cv, *points_iter);
#ifdef CGAL_SWEEP_LINE_DEBUG
cout<<"Sub curve is "<<left_cv<<std::endl;
#endif
//cout<<"Sub curve is "<<*points_iter<<" "<< *next_point<<std::endl;
//X_curve left_cv(*points_iter, *next_point);
pmwx_change_notf->set_curve_attributes(left_cv,
cv_iter->
get_curve().get_parent(),
cv_iter->
get_curve().get_parent()->twin(),
cv_iter->
get_curve().is_first_map());
arr.insert(left_cv, pmwx_change_notf);
cv = right_cv;
}
pmwx_change_notf->set_curve_attributes(right_cv,
cv_iter->get_curve().get_parent(),
cv_iter->
get_curve().get_parent()->twin(),
cv_iter->
get_curve().is_first_map());
arr.insert(right_cv, pmwx_change_notf);
}
}
void build_pm_overlay(const std::list<Curve_node>& curves, Arrangement &arr)
{
#ifdef CGAL_SWEEP_LINE_DEBUG
cout<<"Inserting "<<curves.size()<<" Curve nodes"<<std::endl;
#endif
srand(1); // measuring the time for constructing planar map: we would like
//to have consistent results.
for (std::list<Curve_node>::const_iterator cv_iter = curves.begin();
cv_iter != curves.end(); cv_iter++){
#ifdef CGAL_SWEEP_LINE_DEBUG
cout<<"The Curve is "<<cv_iter->get_curve()<<std::endl;
#endif
X_curve cv = cv_iter->get_curve(), left_cv, r
ight_cv = cv_iter->get_curve();
Halfedge_handle h;
for (Curve_node::Points_const_iterator points_iter =
cv_iter->points_begin(); points_iter != cv_iter->points_end();
points_iter++){
// make surve the splitting is not at the edge points.
if (points_iter == cv_iter->points_begin())
continue;
#ifdef CGAL_SWEEP_LINE_DEBUG
cout<<"Right sub curve is "<<right_cv<<"the splitting point is"
<< *points_iter<<std::endl;
#endif
bool last = false;
++points_iter;
if (points_iter == cv_iter->points_end())
last = true;
points_iter--;
if (last)
left_cv = right_cv; // if the point is the last one, it's the target
point and we can't make split.
else
traits.curve_split(cv, left_cv, right_cv, *points_iter);
#ifdef CGAL_SWEEP_LINE_DEBUG
cout<<"Sub curve is "<<left_cv<<std::endl;
#endif
// now inserting left_cv to the map. We would like to make the
// insertion efficiently, means we know the source vertex in which it
// has to be inserted if this is not the first curve that is inserted.
// Hence we use the functions insert_at_vertices or insert_from_vertex.
bool second_intersection_point = false;
points_iter--;
if (points_iter == cv_iter->points_begin())
second_intersection_point = true;
points_iter++;
// h always holds in its source the left point and in its target the
// right point.
if (second_intersection_point)
h = arr.insert(left_cv);
else{
Locate_type lt;
Halfedge_handle located_h = arr.locate(*points_iter, lt);
if (lt == Arrangement::VERTEX){
Vertex_handle v;
if (located_h->source()->point() == *points_iter)
v = located_h->source();
else
v = located_h->target();
h = arr.insert_at_vertices (left_cv, h->target(), v);
}
else
h = arr.insert_from_vertex (left_cv, h->target(), true);
}
cv = right_cv;
}
//arr.insert(right_cv);
}
}*/
/* //---- debuging functions ----
bool is_valid(const Status_line& status){
std::list<Curve_node> curve_nodes;
std::list<X_curve> subcurves;
for (Status_line::const_iterator iter = status.begin();
iter != status.end(); iter++)
curve_nodes.push_back(iter->first);
get_subcurves(curve_nodes, subcurves);
return (!do_intersect_subcurves(subcurves));
}
// Output function.
void write_pm_overlay(const std::list<Curve_node>& curves)
{
#ifdef CGAL_SWEEP_LINE_DEBUG
cout<<"Inserting "<<curves.size()<<" Curve nodes"<<std::endl;
#endif
std::ofstream f_curves("subcurves_of_sweep.txt");
unsigned int num_of_subcurves = 0;
for (std::list<Curve_node>::const_iterator cv_iter = curves.begin();
cv_iter != curves.end(); cv_iter++){
X_curve cv = cv_iter->get_curve(), left_cv,
right_cv = cv_iter->get_curve();
for (Curve_node::Points_const_iterator points_iter =
cv_iter->points_begin(); points_iter != cv_iter->points_end();
points_iter++){
// make surve the splitting is not at the edge points.
if (points_iter == cv_iter->points_begin())
continue;
num_of_subcurves++;
++points_iter;
if (points_iter == cv_iter->points_end()){
f_curves << right_cv.source().xcoordD() <<" "
<< right_cv.source().ycoordD() <<" "<<
right_cv.target().xcoordD() <<" "<< right_cv.target().ycoordD()
<<std::endl;
break;
}
points_iter--;
traits.curve_split(cv, left_cv, right_cv, *points_iter);
f_curves << left_cv.source().xcoordD() <<" "
<< left_cv.source().ycoordD() <<" "<<
left_cv.target().xcoordD() <<" "<< left_cv.target().ycoordD()
<<std::endl;
cv = right_cv;
}
}
std::cout<<"Total number of subcurves is "<<num_of_subcurves<<std::endl;
}
// graphic function.
void draw_subcurves(const std::list<Curve_node>& curves)
{
double max_x = 10, min_x = -10, min_y = -10;
// debuging.
//cout<<"Inserting "<<curves.size()<<" Curve nodes"<<std::endl;
CGAL::Window_stream W(700, 700, "subcurves of overlay");
W.init(min_x-1, max_x+1, min_y-1);
W.set_mode(leda_src_mode);
W.set_node_width(3);
W.button("finish",2);
W.display();
for (;;) {
double x,y;
int b = W.read_mouse(x,y);
if (b == 2)
break;
for (std::list<Curve_node>::const_iterator cv_iter = curves.begin();
cv_iter != curves.end(); cv_iter++){
X_curve cv = cv_iter->get_curve(), left_cv,
right_cv = cv_iter->get_curve();
for (Curve_node::Points_const_iterator points_iter =
cv_iter->points_begin(); points_iter != cv_iter->points_end();
points_iter++){
W<<CGAL::BLUE;
W << *points_iter;
// make surve the splitting is not at the edge points.
if (points_iter == cv_iter->points_begin())
continue;
++points_iter;
if (points_iter == cv_iter->points_end())
break;
points_iter--;
//cout<<"Right sub curve is "<<right_cv<<"the splitting point is"
<< *points_iter<<std::endl;
// debugging.
//if (traits.curve_compare_y_at_x(cv, *points_iter) !=
//Traits::ON_CURVE){
// cout<<"The point "<<*points_iter<<" is not on the curve "<<cv
<<std::endl;
// break;
// }
traits.curve_split(cv, left_cv, right_cv, *points_iter);
//cout<<"Sub curve is "<<left_cv<<std::endl;
W << CGAL::RED;
W << left_cv;
cv = right_cv;
}
W << CGAL::RED;
W << right_cv;
}
}
}
void get_subcurves(const std::list<Curve_node>& curves, std::list<X_curve>&
subcurves)
{
for (std::list<Curve_node>::const_iterator cv_iter = curves.begin(); cv_iter
!= curves.end(); cv_iter++){
X_curve cv = cv_iter->get_curve(), left_cv,
right_cv = cv_iter->get_curve();
for (Curve_node::Points_const_iterator points_iter =
cv_iter->points_begin(); points_iter != cv_iter->points_end();
points_iter++){
// make surve the splitting is not at the edge points.
if (points_iter == cv_iter->points_begin())
continue;
if (*points_iter == rightmost(traits.curve_source(cv_iter->get_curve()),
traits.curve_target(cv_iter->get_curve())) )
left_cv = right_cv;
else
traits.curve_split(cv, left_cv, right_cv, points_iter->point());
subcurves.push_back(left_cv);
cv = right_cv;
}
//subcurves.push_back(right_cv);
}
}
bool do_intersect_subcurves(const std::list<X_curve>& subcurves)
{
for (std::list<X_curve>::const_iterator scv_iter1 = subcurves.begin();
scv_iter1 != subcurves.end(); scv_iter1++){
for (std::list<X_curve>::const_iterator scv_iter2 = scv_iter1;
scv_iter2 != subcurves.end(); scv_iter2++){
if (scv_iter2 == scv_iter1)
continue;
Point ref_point1, ref_point2, xp1, xp2;
ref_point1 = leftmost(traits.curve_source(*scv_iter1),
traits.curve_target(*scv_iter1));
ref_point2 = leftmost(traits.curve_source(*scv_iter2),
traits.curve_target(*scv_iter2));
if (ref_point1 != ref_point2)
ref_point1 = leftmost(ref_point1, ref_point2);
if (traits.nearest_intersection_to_right(*scv_iter1, *scv_iter2,
ref_point1, xp1, xp2)){
if (xp1 == ref_point1)
xp1 = xp2;
if ( !( (xp1 == traits.curve_source(*scv_iter1) ||
xp1 == traits.curve_target(*scv_iter1) ) &&
(xp1 == traits.curve_source(*scv_iter2) ||
xp1 == traits.curve_target(*scv_iter2) )) ){
#ifdef CGAL_SWEEP_LINE_DEBUG
cout<<"The curves "<<*scv_iter1<<" "<<*scv_iter2<<" are intersected
in the point "<<xp1<<"\n";
#endif
return true;
}
}
}
}
return false;
}
bool is_left(const Point &p1, const Point &p2) const
{ return (CGAL::compare_lexicographically_xy(p1, p2) == SMALLER); }
bool is_right(const Point &p1, const Point &p2) const
{ return (CGAL::compare_lexicographically_xy(p1, p2) == LARGER); }
bool is_lower(const Point &p1, const Point &p2) const
{ return (CGAL::compare_lexicographically_yx(p1, p2) == SMALLER); }
bool is_higher(const Point &p1, const Point &p2) const
{ return (CGAL::compare_lexicographically_yx(p1, p2) == LARGER); }
bool is_same_x(const Point &p1, const Point &p2) const
{ return (traits.compare_x(p1, p2) == EQUAL); }
bool is_same_y(const Point &p1, const Point &p2) const
{ return (traits.compare_y(p1, p2) == EQUAL); }
bool is_same(const Point &p1, const Point &p2) const
{
return (traits.compare_x(p1, p2) == EQUAL) &&
(traits.compare_y(p1, p2) == EQUAL);
}
const Point& leftmost(const Point &p1, const Point &p2) const
{
Comparison_result rx = CGAL::compare_lexicographically_xy(p1, p2);
if (rx == SMALLER)
return p1;
else if (rx == LARGER)
return p2;
else
assert(0);
}
const Point& rightmost(const Point &p1, const Point &p2) const
{
Comparison_result rx = CGAL::compare_lexicographically_xy(p1, p2);
if (rx == SMALLER)
return p2;
else if (rx == LARGER)
return p1;
else
assert(0);
}
//-------------------------------- debuging function.
void print_status(const Status_line& status){
cout<<"Curves on status are\n";
for (Status_line::const_iterator status_iter = status.begin();
status_iter != status.end(); status_iter++){
X_curve_plus cv1 = status_iter->second;
cout<<cv1<<" ";
print_points_on_curves(status_iter->first);
}
cout<<"\n";
}
void print_points_on_curves(const Curve_node& cv){
cout<<"list of points is "<<std::endl;
for (Points_const_iterator p_iter = cv.points_begin();
p_iter != cv.points_end(); p_iter++)
cout<<p_iter->point()<<" ";
cout<<std::endl;
}
Traits traits; */
};
CGAL_END_NAMESPACE
#endif