BWAPI
|
00001 // Copyright (c) 2005, 2009 Tel-Aviv University (Israel). 00002 // All rights reserved. 00003 // 00004 // This file is part of CGAL (www.cgal.org); you may redistribute it under 00005 // the terms of the Q Public License version 1.0. 00006 // See the file LICENSE.QPL distributed with CGAL. 00007 // 00008 // Licensees holding a valid commercial license may use this file in 00009 // accordance with the commercial license agreement provided with the software. 00010 // 00011 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00012 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00013 // 00014 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Arrangement_on_surface_2/include/CGAL/Basic_sweep_line_2.h $ 00015 // $Id: Basic_sweep_line_2.h 50366 2009-07-05 12:56:48Z efif $ 00016 // 00017 // 00018 // Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il> 00019 // (based on old version by Tali Zvi) 00020 00021 #ifndef CGAL_BASIC_SWEEP_LINE_2_H 00022 #define CGAL_BASIC_SWEEP_LINE_2_H 00023 00028 #include <boost/mpl/assert.hpp> 00029 #include <CGAL/assertions.h> 00030 #include <CGAL/memory.h> 00031 #include <CGAL/Sweep_line_2/Sweep_line_functors.h> 00032 #include <CGAL/Sweep_line_2/Sweep_line_subcurve.h> 00033 #include <CGAL/Sweep_line_2/Sweep_line_event.h> 00034 #include <CGAL/Multiset.h> 00035 #include <CGAL/Arrangement_2/Arr_traits_adaptor_2.h> 00036 #include <CGAL/Arr_tags.h> 00037 #include <vector> 00038 #include <algorithm> 00039 #include <iterator> 00040 00041 #ifndef CGAL_SL_VERBOSE 00042 00043 #define CGAL_SL_DEBUG(a) 00044 #define CGAL_PRINT_INSERT(a) 00045 #define CGAL_PRINT_ERASE(a) 00046 #define CGAL_PRINT_NEW_EVENT(p, e) 00047 #define CGAL_PRINT(a) 00048 00049 #else 00050 00051 #include <iostream> 00052 00053 #define CGAL_SL_DEBUG(a) {a} 00054 #define CGAL_PRINT_INSERT(a) { std::cout << "+++ inserting "; \ 00055 (a)->Print(); \ 00056 std::cout << " currentPos = "; \ 00057 PrintEvent(this->m_currentEvent); \ 00058 std::cout << "\n"; \ 00059 } 00060 #define CGAL_PRINT_ERASE(a) { std::cout << "--- erasing " ; \ 00061 (a)->Print(); } 00062 #define CGAL_PRINT_NEW_EVENT(p, e) \ 00063 { std::cout << "%%% a new event was created at " << (p) << std::endl; \ 00064 (e)->Print(); } 00065 #define CGAL_PRINT(a) { std::cout << a ; } 00066 00067 #endif 00068 00069 00070 00071 CGAL_BEGIN_NAMESPACE 00072 00080 template < class Traits_, 00081 class Visitor_, 00082 class Subcurve_ = Sweep_line_subcurve<Traits_>, 00083 typename Event_ = Sweep_line_event<Traits_, Subcurve_>, 00084 typename Allocator_ = CGAL_ALLOCATOR(int) > 00085 class Basic_sweep_line_2 00086 { 00087 public: 00088 00089 typedef Traits_ Traits_2; 00090 typedef Visitor_ Visitor; 00091 typedef Event_ Event; 00092 typedef Subcurve_ Subcurve; 00093 typedef Allocator_ Allocator; 00094 00095 typedef Arr_traits_basic_adaptor_2<Traits_2> Traits_adaptor_2; 00096 typedef typename Traits_adaptor_2::Point_2 Point_2; 00097 typedef typename Traits_adaptor_2::X_monotone_curve_2 X_monotone_curve_2; 00098 00099 typedef typename Traits_adaptor_2::Arr_left_side_tag Arr_left_side_tag; 00100 typedef typename Traits_adaptor_2::Arr_bottom_side_tag Arr_bottom_side_tag; 00101 typedef typename Traits_adaptor_2::Arr_top_side_tag Arr_top_side_tag; 00102 typedef typename Traits_adaptor_2::Arr_right_side_tag Arr_right_side_tag; 00103 00104 BOOST_MPL_ASSERT( 00105 (typename 00106 Arr_sane_identified_tagging< Arr_left_side_tag, Arr_bottom_side_tag, 00107 Arr_top_side_tag, Arr_right_side_tag >::result) 00108 ); 00109 00110 protected: 00111 00112 typedef typename Arr_are_all_sides_oblivious_tag< 00113 Arr_left_side_tag, Arr_bottom_side_tag, 00114 Arr_top_side_tag, Arr_right_side_tag >::result 00115 Are_all_sides_oblivious_tag; 00116 00117 public: 00118 00119 typedef CGAL::Compare_events<Traits_adaptor_2, Event> Compare_events; 00120 typedef Multiset<Event*, Compare_events, Allocator> Event_queue; 00121 typedef typename Event_queue::iterator Event_queue_iterator; 00122 00123 typedef typename Event::Subcurve_iterator 00124 Event_subcurve_iterator; 00125 00126 typedef Sweep_line_event<Traits_2, Subcurve> Base_event; 00127 typedef typename Base_event::Attribute Attribute; 00128 00129 typedef Sweep_line_subcurve<Traits_2> Base_subcurve; 00130 typedef class Curve_comparer<Traits_2, Base_subcurve> Compare_curves; 00131 typedef Multiset<Base_subcurve*, 00132 Compare_curves, 00133 Allocator> Status_line; 00134 typedef typename Status_line::iterator Status_line_iterator; 00135 00136 typedef typename Allocator::template rebind<Event> Event_alloc_rebind; 00137 typedef typename Event_alloc_rebind::other Event_alloc; 00138 00139 typedef typename Allocator::template rebind<Subcurve> Subcurve_alloc_rebind; 00140 typedef typename Subcurve_alloc_rebind::other Subcurve_alloc; 00141 00142 00143 protected: 00144 00148 struct CompEventPtr 00149 { 00150 Comparison_result operator() (Event *e1, Event *e2) const 00151 { 00152 if (e1 < e2) 00153 return (SMALLER); 00154 if (e1 > e2) 00155 return (LARGER); 00156 return (EQUAL); 00157 } 00158 }; 00159 00160 typedef Multiset<Event*, CompEventPtr> Allocated_events_set; 00161 typedef typename Allocated_events_set::iterator Allocated_events_iterator; 00162 00163 // Data members: 00164 const Traits_adaptor_2 * m_traits;// A traits-class object. 00165 bool m_traitsOwner; // Whether this object was allocated by 00166 // this class (and thus should be freed). 00167 00168 Event *m_currentEvent; // The current event. 00169 00170 Compare_curves m_statusLineCurveLess; 00171 // Comparison functor for the status line. 00172 00173 Compare_events m_queueEventLess; // Comparison functor for the event queue. 00174 00175 Event_queue *m_queue; // The event queue (the X-structure). 00176 00177 Subcurve *m_subCurves; // An array of the subcurves. 00178 Status_line m_statusLine; // The status line (the Y-structure). 00179 00180 Allocated_events_set m_allocated_events; 00181 // The events that have been allocated 00182 // (and have not yet been deallocated). 00183 00184 Status_line_iterator m_status_line_insert_hint; 00185 // An iterator of the status line, which 00186 // is used as a hint for insertions. 00187 00188 bool m_is_event_on_above; 00189 // Indicates if the current event is on 00190 // the interior of existing curve. This 00191 // may happen only with events that are 00192 // associated with isolated query points. 00193 00194 Event_alloc m_eventAlloc; // An allocator for the events objects. 00195 Subcurve_alloc m_subCurveAlloc; // An allocator for the subcurve objects. 00196 00197 Event m_masterEvent; // A master Event (created once by the 00198 // constructor) for the allocator's usage. 00199 00200 Subcurve m_masterSubcurve; // A master Subcurve (created once by the 00201 // constructor) for the allocator's usage. 00202 00203 unsigned int m_num_of_subCurves; // Number of subcurves. 00204 00205 Visitor *m_visitor; // The sweep-line visitor that will be 00206 // notified during the sweep. 00207 00208 public: 00209 00214 Basic_sweep_line_2 (Visitor *visitor); 00215 00221 Basic_sweep_line_2 (const Traits_2 *traits, Visitor *visitor); 00222 00224 virtual ~Basic_sweep_line_2 (); 00225 00232 template<class CurveInputIterator> 00233 void sweep (CurveInputIterator curves_begin, 00234 CurveInputIterator curves_end) 00235 { 00236 m_visitor->before_sweep(); 00237 _init_sweep(curves_begin, curves_end); 00238 //m_visitor ->after_init(); 00239 _sweep(); 00240 _complete_sweep(); 00241 m_visitor ->after_sweep(); 00242 } 00243 00257 template<class CurveInputIterator, class PointInputIterator> 00258 void sweep (CurveInputIterator curves_begin, 00259 CurveInputIterator curves_end, 00260 PointInputIterator action_points_begin, 00261 PointInputIterator action_points_end) 00262 { 00263 m_visitor->before_sweep(); 00264 _init_sweep(curves_begin, curves_end); 00265 _init_points(action_points_begin, action_points_end, Base_event::ACTION); 00266 //m_visitor ->after_init(); 00267 _sweep(); 00268 _complete_sweep(); 00269 m_visitor ->after_sweep(); 00270 } 00271 00286 template<class CurveInputIterator, class ActionPointItr,class QueryPointItr> 00287 void sweep (CurveInputIterator curves_begin, 00288 CurveInputIterator curves_end, 00289 ActionPointItr action_points_begin, 00290 ActionPointItr action_points_end, 00291 QueryPointItr query_points_begin, 00292 QueryPointItr query_points_end) 00293 { 00294 m_visitor->before_sweep(); 00295 _init_sweep(curves_begin, curves_end); 00296 _init_points(action_points_begin, action_points_end, Base_event::ACTION); 00297 _init_points(query_points_begin, query_points_end, Base_event::QUERY); 00298 //m_visitor ->after_init(); 00299 _sweep(); 00300 _complete_sweep(); 00301 m_visitor ->after_sweep(); 00302 } 00303 00305 Status_line_iterator status_line_begin () 00306 { 00307 return (m_statusLine.begin()); 00308 } 00309 00311 Status_line_iterator status_line_end() 00312 { 00313 return (m_statusLine.end()); 00314 } 00315 00317 unsigned int status_line_size() const 00318 { 00319 return (m_statusLine.size()); 00320 } 00321 00323 bool is_status_line_empty() const 00324 { 00325 return (m_statusLine.empty()); 00326 } 00327 00329 Event_queue_iterator event_queue_begin() 00330 { 00331 return (m_queue.begin()); 00332 } 00333 00335 Event_queue_iterator event_queue_end() 00336 { 00337 return (m_queue.end()); 00338 } 00339 00341 unsigned int event_queue_size() const 00342 { 00343 return (m_queue.size()); 00344 } 00345 00347 bool is_event_queue_empty() const 00348 { 00349 return (m_queue.empty()); 00350 } 00351 00357 void stop_sweep(); 00358 00364 void deallocate_event(Event* event); 00365 00367 Event* current_event() 00368 { 00369 return (m_currentEvent); 00370 } 00371 00373 const Traits_2 * traits () 00374 { 00375 return m_traits; 00376 } 00377 00378 protected: 00379 00381 void _sweep(); 00382 00384 template <class PointInputIterator> 00385 void _init_points (PointInputIterator points_begin, 00386 PointInputIterator points_end, 00387 Attribute type) 00388 { 00389 PointInputIterator pit; 00390 for (pit = points_begin; pit != points_end; ++pit) 00391 _init_point (*pit, type); 00392 00393 return; 00394 } 00395 00397 template<class CurveInputIterator> 00398 void _init_curves (CurveInputIterator curves_begin, 00399 CurveInputIterator curves_end) 00400 { 00401 CurveInputIterator cit; 00402 unsigned int index = 0; 00403 00404 for (cit = curves_begin; cit != curves_end; ++cit, ++index) 00405 _init_curve (*cit, index); 00406 00407 return; 00408 } 00409 00411 template<class CurveInputIterator> 00412 void _init_sweep (CurveInputIterator curves_begin, 00413 CurveInputIterator curves_end) 00414 { 00415 m_num_of_subCurves = std::distance (curves_begin, curves_end); 00416 00417 _init_structures(); 00418 00419 // Initialize the curves. 00420 _init_curves (curves_begin, curves_end); 00421 return; 00422 } 00423 00425 virtual void _init_structures (); 00426 00428 virtual void _complete_sweep(); 00429 00435 void _init_point (const Point_2& pt, Attribute type); 00436 00442 void _init_curve (const X_monotone_curve_2& curve, unsigned int index); 00443 00450 void _init_curve_end (const X_monotone_curve_2& cv, 00451 Arr_curve_end ind, 00452 Subcurve* sc); 00453 00458 virtual void _handle_left_curves(); 00459 00465 void _handle_event_without_left_curves (); 00466 00471 void _sort_left_curves (); 00472 00474 virtual void _handle_right_curves (); 00475 00482 virtual bool _add_curve_to_right (Event* event, Subcurve* curve, 00483 bool overlap_exist = false); 00484 00486 void _remove_curve_from_status_line (Subcurve *leftCurve); 00487 00497 Event* _allocate_event (const Point_2& pt, Attribute type, 00498 Arr_parameter_space ps_x, Arr_parameter_space ps_y); 00499 00509 Event* _allocate_event_at_open_boundary (Attribute type, 00510 Arr_parameter_space ps_x, 00511 Arr_parameter_space ps_y); 00512 00524 std::pair<Event*, bool> _push_event (const Point_2& pt, 00525 Attribute type, 00526 Arr_parameter_space ps_x, 00527 Arr_parameter_space ps_y, 00528 Subcurve* sc = NULL); 00529 00542 std::pair<Event*, bool> _push_event (const X_monotone_curve_2& cv, 00543 Arr_curve_end ind, 00544 Attribute type, 00545 Arr_parameter_space ps_x, 00546 Arr_parameter_space ps_y, 00547 Subcurve* sc = NULL); 00548 00549 void _update_event_at_open_boundary(Event* e, 00550 const X_monotone_curve_2& cv, 00551 Arr_curve_end ind, 00552 bool is_new) 00553 { 00554 _update_event_at_open_boundary(e, cv, ind, is_new, 00555 Are_all_sides_oblivious_tag()); 00556 } 00557 00558 void _update_event_at_open_boundary(Event* e, 00559 const X_monotone_curve_2& cv, 00560 Arr_curve_end ind, 00561 bool is_new, 00562 Arr_not_all_sides_oblivious_tag) 00563 { 00564 m_visitor->update_event (e, cv, ind, is_new); 00565 } 00566 00567 void _update_event_at_open_boundary(Event* /* e */, 00568 const X_monotone_curve_2& /* cv */, 00569 Arr_curve_end /* ind */, 00570 bool /* is_new */, 00571 Arr_all_sides_oblivious_tag) 00572 { 00573 CGAL_error(); 00574 } 00575 00576 #ifdef CGAL_SL_VERBOSE 00577 void PrintEventQueue(); 00578 void PrintSubCurves(); 00579 void PrintStatusLine(); 00580 void PrintOpenBoundaryType(Arr_parameter_space x, Arr_parameter_space y); 00581 void PrintEvent(const Event* e); 00582 #endif 00583 00584 }; 00585 00586 //DEBUG UTILITIES 00587 #ifdef CGAL_SL_VERBOSE 00588 #include <CGAL/Sweep_line_2/Sweep_line_2_debug.h> 00589 #endif 00590 00591 CGAL_END_NAMESPACE 00592 00593 #include <CGAL/Sweep_line_2/Basic_sweep_line_2_impl.h> 00594 00595 #endif