BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Sweep_line_2/Basic_sweep_line_2_impl.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines