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/Sweep_line_2/Basic_sweep_line_2_impl.h $ 00015 // $Id: Basic_sweep_line_2_impl.h 50366 2009-07-05 12:56:48Z efif $ 00016 // 00017 // 00018 // Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il> 00019 // Efi Fogel <efif@post.tau.ac.il> 00020 // Eric Berberich <ericb@post.tau.ac.il> 00021 // (based on old version by Tali Zvi) 00022 00023 #ifndef CGAL_BASIC_SWEEP_LINE_2_IMPL_H 00024 #define CGAL_BASIC_SWEEP_LINE_2_IMPL_H 00025 00030 CGAL_BEGIN_NAMESPACE 00031 00032 //----------------------------------------------------------------------------- 00033 // Constructor. 00034 // 00035 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc> 00036 Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>:: 00037 Basic_sweep_line_2 (Visitor* visitor) : 00038 m_traits (new Traits_adaptor_2()), 00039 m_traitsOwner (true), 00040 m_statusLineCurveLess (m_traits, &m_currentEvent), 00041 m_queueEventLess (m_traits), 00042 m_queue (new Event_queue (m_queueEventLess)), 00043 m_statusLine (m_statusLineCurveLess), 00044 m_status_line_insert_hint (m_statusLine.begin()), 00045 m_num_of_subCurves (0), 00046 m_visitor (visitor) 00047 { 00048 m_visitor->attach(this); 00049 } 00050 00051 //----------------------------------------------------------------------------- 00052 // Constructor with a given traits-class. 00053 // 00054 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc> 00055 Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>:: 00056 Basic_sweep_line_2 (const Traits_2 * traits, Visitor* visitor) : 00057 m_traits (static_cast<const Traits_adaptor_2*> (traits)), 00058 m_traitsOwner(false), 00059 m_statusLineCurveLess(m_traits, &m_currentEvent), 00060 m_queueEventLess(m_traits), 00061 m_queue(new Event_queue(m_queueEventLess)), 00062 m_statusLine(m_statusLineCurveLess), 00063 m_status_line_insert_hint(m_statusLine.begin()), 00064 m_num_of_subCurves(0), 00065 m_visitor(visitor) 00066 { 00067 m_visitor->attach(this); 00068 } 00069 00070 //----------------------------------------------------------------------------- 00071 // Destrcutor. 00072 // 00073 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc> 00074 Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::~Basic_sweep_line_2() 00075 { 00076 // Free the traits-class object, if we own it. 00077 if(m_traitsOwner) 00078 delete m_traits; 00079 00080 // Free the event queue. 00081 delete m_queue; 00082 00083 // Free all the event that have not been de-allocated so far. 00084 Allocated_events_iterator iter; 00085 Event *p_event; 00086 00087 for (iter = m_allocated_events.begin(); 00088 iter != m_allocated_events.end(); ++iter) 00089 { 00090 p_event = *iter; 00091 m_eventAlloc.destroy(p_event); 00092 m_eventAlloc.deallocate(p_event,1); 00093 } 00094 } 00095 00096 //----------------------------------------------------------------------------- 00097 // Stop the sweep-line process. 00098 // 00099 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc> 00100 void Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::stop_sweep () 00101 { 00102 // Clear the event queue, deallocating all events but the current one 00103 // (the first event in the queue). 00104 Event_queue_iterator qiter= this->m_queue->begin(); 00105 00106 ++qiter; 00107 for(; 00108 qiter != this->m_queue->end(); 00109 ++qiter) 00110 { 00111 this ->deallocate_event(*qiter); 00112 } 00113 00114 // Clear the status line. 00115 this -> m_statusLine.clear(); 00116 m_status_line_insert_hint = this->m_statusLine.begin(); 00117 00118 // Empty the event queue, and leave only the first event there. 00119 CGAL_assertion(!m_queue->empty()); 00120 Event_queue_iterator second = m_queue->begin(); 00121 ++second; 00122 while(second != m_queue->end()) 00123 { 00124 Event_queue_iterator next = second; 00125 ++next; 00126 m_queue->erase(second); 00127 second = next; 00128 } 00129 00130 return; 00131 } 00132 00133 //----------------------------------------------------------------------------- 00134 // Deallocate event object.. 00135 // 00136 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc> 00137 void Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>:: 00138 deallocate_event(Event * event) 00139 { 00140 // Remove the event from the set of allocated events. 00141 m_allocated_events.erase (event); 00142 00143 // Perfrom the actual deallocation. 00144 m_eventAlloc.destroy(event); 00145 m_eventAlloc.deallocate(event,1); 00146 return; 00147 } 00148 00149 //----------------------------------------------------------------------------- 00150 // Perform the main sweep-line loop. 00151 // 00152 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc> 00153 void Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_sweep () 00154 { 00155 CGAL_SL_DEBUG( 00156 { 00157 CGAL_PRINT("Ordered sequence of " << m_queue->size() 00158 << " initial events:\n"); 00159 Event_queue_iterator eventIter1 = m_queue->begin(); 00160 while (eventIter1 != m_queue->end()) { 00161 00162 CGAL_PRINT("* "); 00163 CGAL_SL_DEBUG(PrintEvent(*eventIter1);); 00164 CGAL_PRINT ( "\n"); 00165 eventIter1++; 00166 } 00167 } 00168 ) 00169 00170 // Looping over the events in the queue. 00171 Event_queue_iterator eventIter = m_queue->begin(); 00172 00173 while (eventIter != m_queue->end()) 00174 { 00175 // Get the next event from the queue. 00176 m_currentEvent = *eventIter; 00177 00178 CGAL_PRINT("------------- "); 00179 CGAL_SL_DEBUG(PrintEvent(m_currentEvent);); 00180 CGAL_PRINT ( " --------------\n"); 00181 CGAL_SL_DEBUG(PrintStatusLine(); 00182 m_currentEvent->Print();); 00183 00184 // Handle the subcurves that are to the left of the event point (i.e., 00185 // subcurves that we are done with). 00186 _handle_left_curves(); 00187 00188 // Handle the subcurves to the right of the event point, reorder them 00189 // and test for intersections between them and their immediate neighbors 00190 // on the status line. 00191 _handle_right_curves(); 00192 00193 // Inform the visitor about the event. The visitor also determines whether 00194 // it is possible to deallocate the event now, or will it be deallocated 00195 // later (at the visitor's responsibility). 00196 if (m_visitor->after_handle_event(m_currentEvent, 00197 m_status_line_insert_hint, 00198 m_is_event_on_above)) 00199 { 00200 // It is possible to deallocate the event: 00201 deallocate_event(m_currentEvent); 00202 } 00203 00204 // We are done with the current event - remove it from the queue. 00205 m_queue->erase(eventIter); 00206 eventIter = m_queue->begin(); 00207 } 00208 00209 return; 00210 } 00211 00212 //----------------------------------------------------------------------------- 00213 // Initialize the data structures for the sweep-line algorithm. 00214 // 00215 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc> 00216 void Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_init_structures() 00217 { 00218 CGAL_assertion(m_queue->empty()); 00219 CGAL_assertion((m_statusLine.size() == 0)); 00220 00221 // Allocate all of the Subcurve objects as one block. 00222 m_subCurves = m_subCurveAlloc.allocate(m_num_of_subCurves); 00223 return; 00224 } 00225 00226 //----------------------------------------------------------------------------- 00227 // Complete the sweep (complete the data structures). 00228 // 00229 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc> 00230 void Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_complete_sweep () 00231 { 00232 CGAL_assertion(m_queue->empty()); 00233 CGAL_assertion((m_statusLine.size() == 0)); 00234 00235 // Free all subcurve objects. 00236 unsigned int i; 00237 for (i = 0 ; i < m_num_of_subCurves; ++i) 00238 m_subCurveAlloc.destroy (m_subCurves + i); 00239 00240 if (m_num_of_subCurves > 0) 00241 m_subCurveAlloc.deallocate (m_subCurves, m_num_of_subCurves); 00242 00243 return; 00244 } 00245 00246 //----------------------------------------------------------------------------- 00247 // Initialize an event associated with a point. 00248 // 00249 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc> 00250 void Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>:: 00251 _init_point (const Point_2& pt, Attribute type) 00252 { 00253 // Create the event, or obtain an existing event in the queue. 00254 // Note that an isolated point does not have any boundary conditions. 00255 const std::pair<Event*, bool>& pair_res = _push_event (pt, type, 00256 ARR_INTERIOR, 00257 ARR_INTERIOR); 00258 00259 bool is_new = pair_res.second; 00260 m_visitor->update_event(pair_res.first, pt, is_new); 00261 00262 return; 00263 } 00264 00265 //----------------------------------------------------------------------------- 00266 // Initialize the events associated with an x-monotone curve. 00267 // 00268 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc> 00269 void Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>:: 00270 _init_curve (const X_monotone_curve_2& curve, unsigned int index) 00271 { 00272 // Construct an initialize a subcurve object. 00273 m_subCurveAlloc.construct (m_subCurves + index, m_masterSubcurve); 00274 00275 (m_subCurves + index)->init(curve); 00276 00277 // Create two events associated with the curve ends. 00278 _init_curve_end (curve, ARR_MAX_END, m_subCurves + index); 00279 _init_curve_end (curve, ARR_MIN_END, m_subCurves + index); 00280 00281 return; 00282 } 00283 00284 //----------------------------------------------------------------------------- 00285 // Initialize an event associated with an x-monotone curve end. 00286 // 00287 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc> 00288 void Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>:: 00289 _init_curve_end(const X_monotone_curve_2& cv, Arr_curve_end ind, Subcurve* sc) 00290 { 00291 // Get the boundary conditions of the curve end. 00292 const Attribute end_attr = 00293 (ind == ARR_MIN_END) ? Base_event::LEFT_END : Base_event::RIGHT_END; 00294 00295 Arr_parameter_space ps_x = m_traits->parameter_space_in_x_2_object()(cv, ind); 00296 Arr_parameter_space ps_y = m_traits->parameter_space_in_y_2_object()(cv, ind); 00297 00298 // Create the corresponding event an push it into the event queue. 00299 std::pair<Event*, bool> pair_res; 00300 00301 if (m_traits->is_closed_2_object()(cv, ind)) { 00302 // The curve end is closed and thus associated with a valid endpoint. 00303 const Point_2& pt = (ind == ARR_MIN_END) ? 00304 m_traits->construct_min_vertex_2_object()(cv) : 00305 m_traits->construct_max_vertex_2_object()(cv); 00306 00307 if (ps_x == ARR_INTERIOR && ps_y == ARR_INTERIOR) { 00308 pair_res = _push_event (pt, end_attr, ps_x, ps_y, sc); 00309 } else { 00310 pair_res = _push_event (cv, ind, end_attr, ps_x, ps_y, sc); 00311 } 00312 00313 // Inform the visitor in case we updated an existing event. 00314 Event *e = pair_res.first; 00315 00316 CGAL_assertion (e->is_closed()); 00317 m_visitor->update_event (e, pt, cv, ind, pair_res.second); 00318 } 00319 else 00320 { 00321 // The curve end is open, insert it into the event queue. 00322 pair_res = _push_event (cv, ind, end_attr, ps_x, ps_y, sc); 00323 00324 // Inform the visitor in case we updated an existing event. 00325 Event *e = pair_res.first; 00326 00327 CGAL_assertion (! e->is_closed()); 00328 _update_event_at_open_boundary(e, cv, ind, pair_res.second); 00329 } 00330 00331 return; 00332 } 00333 00334 //----------------------------------------------------------------------------- 00335 // Handle the subcurves to the left of the current event point. 00336 // 00337 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc> 00338 void Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_handle_left_curves() 00339 { 00340 CGAL_PRINT("Handling left curve" << std::endl;); 00341 00342 m_is_event_on_above = false; 00343 00344 if(! m_currentEvent->has_left_curves()) 00345 { 00346 // The current event does not have any incident left subcurves, so we 00347 // should find a place for it in the status line (the function we call 00348 // update the m_status_line_insert_hint and m_is_event_on_above members). 00349 // We also notify the visitor on the new event we are about to handle. 00350 _handle_event_without_left_curves(); 00351 00352 if (m_currentEvent->is_closed()) 00353 { 00354 if (m_is_event_on_above) 00355 { 00356 // The current event is on the interior of existing curve on the 00357 // status line. Since the basic sweep does not allow intersections, 00358 // this is possible only if the event is an isolated query point. 00359 CGAL_assertion (! m_currentEvent->has_right_curves() && 00360 m_currentEvent->is_query()); 00361 00362 //m_is_event_on_above = true; 00363 m_visitor->before_handle_event(m_currentEvent); 00364 } 00365 else 00366 m_visitor->before_handle_event(m_currentEvent); 00367 } 00368 else 00369 m_visitor->before_handle_event(m_currentEvent); 00370 00371 // Nothing else to do (no left curves). 00372 return; 00373 } 00374 00375 CGAL_PRINT("left curves before sorting: "<<"\n";); 00376 CGAL_SL_DEBUG(if (m_currentEvent->left_curves_begin() != 00377 m_currentEvent->left_curves_end() ) 00378 { 00379 m_currentEvent->Print(); 00380 }); 00381 00382 // Use the status-line to sort all left subcurves incident to the current 00383 // event (no geometric comparisons are neede at all). 00384 _sort_left_curves(); 00385 00386 // Now the event is updated, with its left subcurved properly sorted, and 00387 // we can inform the visitor that we are about to handle this event. 00388 m_visitor->before_handle_event(m_currentEvent); 00389 00390 CGAL_PRINT("left curves after sorting: "<<"\n";); 00391 CGAL_SL_DEBUG(if (m_currentEvent->left_curves_begin() != 00392 m_currentEvent->left_curves_end() ) 00393 { 00394 m_currentEvent->Print(); 00395 }); 00396 00397 // Remove all left subcurves from the status line, and inform the visitor 00398 // that we are done handling these subcurves. 00399 Event_subcurve_iterator left_iter = m_currentEvent->left_curves_begin(); 00400 00401 while (left_iter != m_currentEvent->left_curves_end()) 00402 { 00403 Subcurve *left_sc = *left_iter; 00404 00405 m_visitor->add_subcurve (left_sc->last_curve(), left_sc); 00406 ++left_iter; 00407 00408 _remove_curve_from_status_line (left_sc); 00409 } 00410 CGAL_PRINT( "Handling left curve END" << std::endl;); 00411 00412 return; 00413 } 00414 00415 //----------------------------------------------------------------------------- 00416 // Handle an event that does not have any incident left curves. 00417 // 00418 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc> 00419 void Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>:: 00420 _handle_event_without_left_curves() 00421 { 00422 // Check if the event is a boundary event or not. 00423 const Arr_parameter_space ps_x = m_currentEvent->parameter_space_in_x(); 00424 const Arr_parameter_space ps_y = m_currentEvent->parameter_space_in_y(); 00425 00426 if (ps_x == ARR_INTERIOR && ps_y == ARR_INTERIOR) 00427 { 00428 // The event is associated with a valid point - locate the position of 00429 // this point on the status line (note this point may be located on a 00430 // subcurve in the status line). 00431 const std::pair<Status_line_iterator, bool>& pair_res = 00432 m_statusLine.find_lower (m_currentEvent->point(), 00433 m_statusLineCurveLess); 00434 00435 m_status_line_insert_hint = pair_res.first; 00436 m_is_event_on_above = pair_res.second; 00437 00438 return; 00439 } 00440 00441 // We have a boundary event, so we can easily locate a plave for it in the 00442 // status line. 00443 00444 if (ps_x == ARR_LEFT_BOUNDARY) 00445 { 00446 // We are still sweeping the left boundary, so by the way we have ordered 00447 // the events in the queue, we know that the new event should be placed 00448 // above all other subcurves in the status line. 00449 m_status_line_insert_hint = m_statusLine.end(); 00450 } 00451 else 00452 { 00453 // Note that an event with a positive boundary condition at x can only 00454 // represent a right end of a curve. 00455 CGAL_assertion (ps_x != ARR_RIGHT_BOUNDARY); 00456 00457 // If the sign of the boundary in y is negative, the event should be 00458 // inserted below all other subcurves; if it is possitive, the event is 00459 // above all other subcurves. 00460 if (ps_y == ARR_BOTTOM_BOUNDARY) 00461 { 00462 m_status_line_insert_hint = m_statusLine.begin(); 00463 } 00464 else 00465 { 00466 CGAL_assertion (ps_y == ARR_TOP_BOUNDARY); 00467 m_status_line_insert_hint = m_statusLine.end(); 00468 } 00469 } 00470 00471 return; 00472 } 00473 00474 //----------------------------------------------------------------------------- 00475 // Sort the left subcurves of an event point according to their order in 00476 // their status line (no geometric comprasions are needed). 00477 // 00478 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc> 00479 void Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_sort_left_curves() 00480 { 00481 CGAL_assertion (m_currentEvent->has_left_curves()); 00482 00483 // Get the first curve associated with the event and its position on the 00484 // status line. We proceed from this position up the status line until 00485 // we encounter a subcurve that is not associated with the current event. 00486 Subcurve *curve = *(m_currentEvent->left_curves_begin()); 00487 Status_line_iterator sl_iter = curve->hint(); 00488 CGAL_assertion (*sl_iter == curve); 00489 00490 for (++sl_iter; sl_iter != m_statusLine.end(); ++sl_iter) 00491 { 00492 if (std::find (m_currentEvent->left_curves_begin(), 00493 m_currentEvent->left_curves_end(), 00494 *sl_iter) == m_currentEvent->left_curves_end()) 00495 break; 00496 } 00497 Status_line_iterator end = sl_iter; 00498 00499 sl_iter = curve->hint(); 00500 if (sl_iter == m_statusLine.begin()) 00501 { 00502 // In case the lowest subcurve in the status line is associated with the 00503 // current event, we have the range of (sorted) subcurves ready. We 00504 // associate this range with the event, so the curves are now sorted 00505 // according to their vertical positions immediately to the left of the 00506 // event. 00507 m_currentEvent->replace_left_curves (sl_iter,end); 00508 return; 00509 } 00510 00511 // Go down the status line until we encounter a subcurve that is not 00512 // associated with the current event. 00513 --sl_iter; 00514 for (;sl_iter != m_statusLine.begin(); --sl_iter) 00515 { 00516 if (std::find (m_currentEvent->left_curves_begin(), 00517 m_currentEvent->left_curves_end(), 00518 *sl_iter) == m_currentEvent->left_curves_end()) 00519 { 00520 // Associate the sorted range of subcurves with the event. 00521 m_currentEvent->replace_left_curves(++sl_iter,end); 00522 return; 00523 } 00524 } 00525 00526 // Check if the subcurve at the current iterator position should be 00527 // associated with the current event, and select the (sorted) range of 00528 // subcurves accordingly. 00529 if (std::find (m_currentEvent->left_curves_begin(), 00530 m_currentEvent->left_curves_end(), 00531 *sl_iter) == m_currentEvent->left_curves_end()) 00532 { 00533 m_currentEvent->replace_left_curves(++sl_iter,end);; 00534 } 00535 else 00536 { 00537 m_currentEvent->replace_left_curves (sl_iter,end); 00538 } 00539 00540 return; 00541 } 00542 00543 //----------------------------------------------------------------------------- 00544 // Handle the subcurves to the right of the current event point. 00545 // 00546 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc> 00547 void Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_handle_right_curves() 00548 { 00549 CGAL_PRINT("Handling right curves (" ;); 00550 CGAL_SL_DEBUG(PrintEvent(m_currentEvent);); 00551 CGAL_PRINT(")\n";); 00552 00553 // We have nothing to do if the current event does not have any incident 00554 // right subcurves. 00555 if (! m_currentEvent->has_right_curves()) 00556 return; 00557 00558 // Loop over the curves to the right of the current event and handle them: 00559 // Since the curves are non intersecting, the event can represents the 00560 // left end of the right curves and we have no prior information from the 00561 // order of the left subcurves. Thus, we just insert the curves to the 00562 // status line. 00563 Event_subcurve_iterator curr = m_currentEvent->right_curves_begin(); 00564 Event_subcurve_iterator right_end = m_currentEvent->right_curves_end(); 00565 Status_line_iterator sl_iter; 00566 00567 while (curr != right_end) 00568 { 00569 CGAL_PRINT_INSERT(*curr); 00570 sl_iter = m_statusLine.insert_before (m_status_line_insert_hint, 00571 *curr); 00572 ((Subcurve*)(*curr))->set_hint(sl_iter); 00573 00574 CGAL_SL_DEBUG(PrintStatusLine();); 00575 ++curr; 00576 } 00577 00578 CGAL_SL_DEBUG(PrintStatusLine();); 00579 return; 00580 } 00581 00582 //----------------------------------------------------------------------------- 00583 // Add a subcurve to the right of an event point. 00584 // 00585 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc> 00586 bool Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_add_curve_to_right 00587 (Event* event, Subcurve* curve, 00588 bool /* overlap_exist */) 00589 { 00590 std::pair<bool, Event_subcurve_iterator> pair_res = 00591 event->add_curve_to_right(curve, m_traits); 00592 00593 CGAL_assertion(!pair_res.first); 00594 return (false); 00595 } 00596 00597 00598 //----------------------------------------------------------------------------- 00599 // Remove a curve from the status line. 00600 // 00601 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc> 00602 void Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>:: 00603 _remove_curve_from_status_line (Subcurve *sc) 00604 { 00605 CGAL_PRINT("remove_curve_from_status_line\n";); 00606 CGAL_SL_DEBUG(PrintStatusLine();); 00607 CGAL_SL_DEBUG(sc->Print();); 00608 00609 // Get the position of the subcurve on the status line. 00610 Status_line_iterator sl_iter = sc->hint(); 00611 CGAL_assertion (sl_iter != m_statusLine.end()); 00612 00613 // The position of the next event can be right after the deleted subcurve. 00614 m_status_line_insert_hint = sl_iter; 00615 ++m_status_line_insert_hint; 00616 00617 // Erase the subcurve from the status line. 00618 m_statusLine.erase (sl_iter); 00619 CGAL_PRINT("remove_curve_from_status_line Done\n";) 00620 return; 00621 } 00622 00623 //----------------------------------------------------------------------------- 00624 // Allocate an event object associated with a valid point. 00625 // 00626 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc> 00627 typename Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::Event* 00628 Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>:: 00629 _allocate_event (const Point_2& pt, Attribute type, 00630 Arr_parameter_space ps_x, Arr_parameter_space ps_y) 00631 { 00632 // Allocate the event. 00633 Event *e = m_eventAlloc.allocate(1); 00634 m_eventAlloc.construct(e, m_masterEvent); 00635 e->init (pt, type, ps_x, ps_y); 00636 00637 // Insert it to the set of allocated events. 00638 m_allocated_events.insert(e); 00639 return (e); 00640 } 00641 00642 //----------------------------------------------------------------------------- 00643 // Allocate an event at open boundary, 00644 // which is not associated with a valid point. 00645 // 00646 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc> 00647 typename Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::Event* 00648 Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>:: 00649 _allocate_event_at_open_boundary(Attribute type, 00650 Arr_parameter_space ps_x, 00651 Arr_parameter_space ps_y) 00652 { 00653 Event *e = m_eventAlloc.allocate(1); 00654 m_eventAlloc.construct(e, m_masterEvent); 00655 e->init_at_open_boundary (type, ps_x, ps_y); 00656 00657 m_allocated_events.insert(e); 00658 return (e); 00659 } 00660 00661 //----------------------------------------------------------------------------- 00662 // Push a closed event point into the event queue. 00663 // 00664 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc> 00665 std::pair<typename Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::Event*, 00666 bool> 00667 Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>:: 00668 _push_event (const Point_2& pt, Attribute type, 00669 Arr_parameter_space ps_x, Arr_parameter_space ps_y, Subcurve* sc) 00670 { 00671 // Look for the point in the event queue. 00672 Event* e; 00673 m_queueEventLess.set_parameter_space_in_x (ps_x); 00674 m_queueEventLess.set_parameter_space_in_y (ps_y); 00675 00676 const std::pair<Event_queue_iterator, bool>& pair_res = 00677 m_queue->find_lower(pt, m_queueEventLess); 00678 const bool exist = pair_res.second; 00679 00680 if (! exist) 00681 { 00682 // The point is not found in the event queue - create a new event and 00683 // insert it into the queue. 00684 e = _allocate_event (pt, type, ps_x, ps_y); 00685 } 00686 else 00687 { 00688 // The event associated with the given point already exists in the queue, 00689 // so we just have to update it. 00690 e = *(pair_res.first); 00691 CGAL_assertion (e->is_closed()); 00692 00693 e->set_attribute(type); 00694 } 00695 00696 // If we are given a subcurve that the event represents one of its 00697 // endpoints, update the event and the subcurve records accordingly. 00698 // Note that this must be done before we actually insert the new event 00699 // into the event queue. 00700 if (sc != NULL) 00701 { 00702 if (type == Base_event::LEFT_END) 00703 { 00704 sc->set_left_event (e); 00705 _add_curve_to_right (e, sc); 00706 } 00707 else 00708 { 00709 CGAL_assertion (type == Base_event::RIGHT_END); 00710 sc->set_right_event (e); 00711 e->add_curve_to_left (sc); 00712 } 00713 } 00714 00715 if (! exist) 00716 { 00717 // Insert the new event into the queue using the hint we got when we 00718 // looked for it. 00719 m_queue->insert_before (pair_res.first, e); 00720 } 00721 CGAL_PRINT_NEW_EVENT(pt, e); 00722 00723 // Return the resulting event and a flag indicating whether we have created 00724 // a new event. 00725 return (std::make_pair(e, !exist)); 00726 } 00727 00728 //----------------------------------------------------------------------------- 00729 // Push an event point associated with a curve end into the event queue. 00730 // 00731 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc> 00732 std::pair<typename Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::Event*, 00733 bool> 00734 Basic_sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>:: 00735 _push_event (const X_monotone_curve_2& cv, Arr_curve_end ind, 00736 Attribute type, 00737 Arr_parameter_space ps_x, Arr_parameter_space ps_y, 00738 Subcurve* sc) 00739 { 00740 //cv has no member named 'base' 00741 //std::cout << "cv: " << cv.base() << std::endl; 00742 00743 // Look for the curve end in the event queue. 00744 Event* e; 00745 00746 m_queueEventLess.set_parameter_space_in_x (ps_x); 00747 m_queueEventLess.set_parameter_space_in_y (ps_y); 00748 m_queueEventLess.set_index (ind); 00749 00750 const std::pair<Event_queue_iterator, bool>& pair_res = 00751 m_queue->find_lower (cv, m_queueEventLess); 00752 const bool exist = pair_res.second; 00753 00754 if (! exist) 00755 { 00756 // The curve end is not found in the event queue - create a new event and 00757 // insert it into the queue. 00758 if (m_traits->is_closed_2_object()(cv, ind)) 00759 { 00760 // The curve end is closed and so it is associated with a valid 00761 // point. 00762 const Point_2& pt = (ind == ARR_MIN_END) ? 00763 m_traits->construct_min_vertex_2_object()(cv) : 00764 m_traits->construct_max_vertex_2_object()(cv); 00765 00766 e = _allocate_event (pt, type, ps_x, ps_y); 00767 } 00768 else 00769 { 00770 // The curve end is open, so we create an event at open boundary. 00771 e = _allocate_event_at_open_boundary (type, ps_x, ps_y); 00772 } 00773 } 00774 else 00775 { 00776 // The event associated with the given curve end already exists in the 00777 // queue, so we just have to update it. 00778 e = *(pair_res.first); 00779 CGAL_assertion (e->parameter_space_in_x() == ps_x && 00780 e->parameter_space_in_y() == ps_y); 00781 00782 e->set_attribute(type); 00783 } 00784 00785 // If we are given a subcurve that the event represents one of its 00786 // endpoints, update the event and the subcurve records accordingly. 00787 // Note that this must be done before we actually insert the new event 00788 // into the event queue. 00789 if (sc != NULL) 00790 { 00791 if (type == Base_event::LEFT_END) 00792 { 00793 sc->set_left_event(e); 00794 _add_curve_to_right(e, sc); 00795 } 00796 else 00797 { 00798 CGAL_assertion (type == Base_event::RIGHT_END); 00799 sc->set_right_event(e); 00800 e->add_curve_to_left(sc); 00801 } 00802 } 00803 00804 if (! exist) 00805 { 00806 // Insert the new event into the queue using the hint we got when we 00807 // looked for it. 00808 m_queue->insert_before (pair_res.first, e); 00809 } 00810 00811 return (std::make_pair(e, !exist)); 00812 } 00813 00814 CGAL_END_NAMESPACE 00815 00816 #endif