BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Sweep_line_2/Sweep_line_2_impl.h
Go to the documentation of this file.
00001 // Copyright (c) 2005  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/Sweep_line_2_impl.h $
00015 // $Id: Sweep_line_2_impl.h 49772 2009-06-03 21:25:53Z eric $
00016 // 
00017 //
00018 // Author(s)     : Baruch Zukerman <baruchzu@post.tau.ac.il>
00019 //                 Efi Fogel       <efif@post.tau.ac.il>
00020 //                 (based on old version by Tali Zvi)
00021 
00022 #ifndef CGAL_SWEEP_LINE_2_IMPL_H
00023 #define CGAL_SWEEP_LINE_2_IMPL_H
00024 
00029 CGAL_BEGIN_NAMESPACE
00030 
00031 //-----------------------------------------------------------------------------
00032 // Initialize the data structures for the sweep-line algorithm.
00033 //
00034 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc>
00035 void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_init_structures()
00036 {
00037   // Initailize the structures maintained by the base sweep-line class.
00038   Base::_init_structures();
00039   
00040   // Resize the hash to be O(2*n), where n is the number of input curves.
00041   m_curves_pair_set.resize (2 * this->m_num_of_subCurves);
00042 }
00043 
00044 //-----------------------------------------------------------------------------
00045 // Complete the sweep (complete the data structures).
00046 //
00047 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc>
00048 void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_complete_sweep()
00049 {
00050   // Complete the sweep process using base sweep-line class.
00051   Base::_complete_sweep();
00052   
00053   // Clean the set of curve pairs for which we have computed intersections.
00054   m_curves_pair_set.clear();
00055   
00056   // Free all overlapping subcurves we have created.
00057   Subcurve_iterator   itr;
00058   for (itr = m_overlap_subCurves.begin();
00059        itr != m_overlap_subCurves.end();
00060        ++itr)
00061   {
00062     this->m_subCurveAlloc.destroy(*itr);
00063     this->m_subCurveAlloc.deallocate(*itr, 1);
00064   }
00065   
00066   m_overlap_subCurves.clear();
00067 }
00068 
00069 //-----------------------------------------------------------------------------
00070 // Handle the subcurves to the left of the current event point.
00071 //
00072 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc>
00073 void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_handle_left_curves ()
00074 { 
00075   CGAL_PRINT("Handling left curve" << std::endl;);
00076   
00077   this->m_is_event_on_above = false;
00078   
00079   if (! this->m_currentEvent->has_left_curves())
00080   {
00081     // In case the current event has no left subcurves incident to it, we have
00082     // to locate a place for it in the status line.
00083     CGAL_PRINT(" - handling special case " << std::endl;);
00084     this->_handle_event_without_left_curves();
00085     
00086     Status_line_iterator sl_pos = this->m_status_line_insert_hint;
00087     
00088     if (this->m_is_event_on_above)
00089     {
00090       // The current event point starts at the interior of a subcurve that
00091       // already exists in the status line (this may also indicate an overlap).
00092       if (! this->m_currentEvent->has_right_curves())
00093       {
00094         // The event is an isolated point.
00095         if (this->m_currentEvent->is_query())
00096         {
00097           // In case of a query point, just notify the visitor about it.
00098           this->m_is_event_on_above = true;
00099           this->m_visitor->before_handle_event (this->m_currentEvent);
00100           return;
00101         }
00102 
00103         // In case of an isolated action point, mark the point at a "weak"
00104         // intersection.
00105         CGAL_assertion(this->m_currentEvent->is_action());
00106         this->m_currentEvent->set_weak_intersection();
00107       }  
00108       
00109       // Obtain the subcurve that contains the current event, and add it to
00110       // the left curves incident to the event.
00111       Subcurve *sc = static_cast<Subcurve*>(*(this->
00112                                               m_status_line_insert_hint));
00113       const X_monotone_curve_2&  last_curve = sc->last_curve();
00114 
00115       this->m_currentEvent->set_weak_intersection();
00116       this->m_visitor->update_event(this->m_currentEvent, sc);
00117       this->m_currentEvent->add_curve_to_left(sc);
00118       
00119       // If necessary, add the subcurves as a right incident curve as well.
00120       // We also check for overlaps.
00121       bool       is_overlap = _add_curve_to_right(this->m_currentEvent, sc);
00122       
00123       this->m_traits->split_2_object() (last_curve,
00124                                         this->m_currentEvent->point(), 
00125                                         sub_cv1, sub_cv2);
00126       
00127       ++(this->m_status_line_insert_hint); 
00128       
00129       if (is_overlap)
00130       {
00131         // Handle overlaps.
00132         this->m_visitor->before_handle_event (this->m_currentEvent);
00133         this->m_visitor->add_subcurve (sub_cv1, sc);
00134         this->m_statusLine.erase (sl_pos);
00135         return;
00136       }
00137       
00138     }
00139     else
00140     {
00141       // The event is not located on any subcurve.
00142       this->m_visitor->before_handle_event(this->m_currentEvent);
00143       return;
00144     }
00145   }
00146     
00147   CGAL_PRINT("left curves before sorting: "<<"\n";);
00148   CGAL_SL_DEBUG(if (this->m_currentEvent->left_curves_begin() != 
00149                     this->m_currentEvent->left_curves_end() )
00150                 {
00151                   this->m_currentEvent->Print();
00152                 });
00153   _fix_overlap_subcurves();
00154   this->_sort_left_curves();
00155   this->m_visitor->before_handle_event(this->m_currentEvent);
00156   
00157   CGAL_PRINT("left curves after sorting: "<<"\n";);
00158   CGAL_SL_DEBUG(if (this->m_currentEvent->left_curves_begin() != 
00159                     this->m_currentEvent->left_curves_end() )
00160                 {
00161                   this->m_currentEvent->Print();
00162                 });
00163   
00164   // Check if the curve should be removed for good.
00165   bool remove_for_good = false; 
00166   
00167   Event_subcurve_iterator left_iter = 
00168     this->m_currentEvent->left_curves_begin();
00169 
00170   while(left_iter != this->m_currentEvent->left_curves_end())
00171   {
00172     Subcurve *leftCurve = *left_iter; 
00173     
00174     if((Event*)leftCurve->right_event() == this->m_currentEvent)
00175     {  
00176       // we are done with that subcurve (current event point is his right
00177       // end point) so we remove it from the status line for good.
00178       remove_for_good = true;
00179       this->m_visitor->add_subcurve(leftCurve->last_curve(), leftCurve);
00180     }
00181     else
00182     {
00183       // curren event splits the subcurve.
00184       const X_monotone_curve_2 &lastCurve = leftCurve->last_curve();
00185       
00186       this->m_traits->split_2_object()(lastCurve,
00187                                        this->m_currentEvent->point(),
00188                                        sub_cv1,
00189                                        sub_cv2);
00190       this->m_visitor->add_subcurve(sub_cv1, leftCurve);
00191       leftCurve->set_last_curve(sub_cv2);
00192     }
00193     ++left_iter;
00194     
00195     //remove curve from the status line (also checks intersection 
00196     //between the neighbouring curves,only if the curve is removed for good)
00197     _remove_curve_from_status_line(leftCurve, remove_for_good);    
00198   }
00199   CGAL_PRINT( "Handling left curve END" << std::endl;);
00200   
00201   return;
00202 }
00203   
00204 //-----------------------------------------------------------------------------
00205 // Handle the subcurves to the right of the current event point.
00206 //
00207 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc>
00208 void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_handle_right_curves ()
00209 {
00210   CGAL_PRINT("Handling right curves (" ;);
00211   CGAL_SL_DEBUG(this->PrintEvent(this->m_currentEvent););
00212   CGAL_PRINT(")\n";);
00213   
00214   if(! this->m_currentEvent->has_right_curves())
00215     return;
00216   
00217   // Loop over the curves to the right of the status line and handle them:
00218   // - If we are at the beginning of the curve, we insert it to the status 
00219   //   line, then we look if it intersects any of its neighbors.
00220   // - If we are at an intersection point between two curves, we add them
00221   //   to the status line and attempt to intersect them with their neighbors
00222   // - We also check to see if the two intersect again to the right of the 
00223   //   point.
00224   
00225   Event_subcurve_iterator currentOne = 
00226     this->m_currentEvent->right_curves_begin();
00227   Event_subcurve_iterator rightCurveEnd = 
00228     this->m_currentEvent->right_curves_end();
00229   
00230   CGAL_PRINT_INSERT(*currentOne);
00231   
00232   Status_line_iterator slIter = 
00233     this->m_statusLine.insert_before (this->m_status_line_insert_hint, 
00234                                       *currentOne);
00235   ((Subcurve*)(*currentOne))->set_hint(slIter);
00236   
00237   CGAL_SL_DEBUG(this->PrintStatusLine(););
00238   if ( slIter != this->m_statusLine.begin() )
00239   { 
00240     //  get the previous curve in the y-str
00241     Status_line_iterator prev = slIter; --prev;
00242     _intersect(static_cast<Subcurve*>(*prev),
00243                static_cast<Subcurve*>(*slIter));
00244   }
00245   
00246   Event_subcurve_iterator prevOne = currentOne;
00247   ++currentOne;
00248   while (currentOne != rightCurveEnd)
00249   {
00250     CGAL_PRINT_INSERT(*currentOne);
00251     slIter = this->m_statusLine.insert_before
00252       (this->m_status_line_insert_hint, *currentOne);
00253     ((Subcurve*)(*currentOne))->set_hint(slIter);
00254     
00255     CGAL_SL_DEBUG(this->PrintStatusLine(););
00256     
00257     // If the two curves used to be neighbours before, we do not need to
00258     // intersect them again.
00259     if (!this->m_currentEvent->are_left_neighbours
00260         (static_cast<Subcurve*>(*currentOne),
00261          static_cast<Subcurve*>(*prevOne)))
00262     {
00263       _intersect(*prevOne, *currentOne);
00264     }
00265 
00266     prevOne = currentOne;
00267     ++currentOne;
00268   }        
00269       
00270   CGAL_SL_DEBUG(this->PrintStatusLine(););
00271   
00272   //the next Subcurve at the status line 
00273   ++slIter;
00274   if ( slIter != this->m_statusLine.end() )
00275     _intersect( static_cast<Subcurve*>(*prevOne),
00276                 static_cast<Subcurve*>(*slIter));
00277 }
00278 
00279 //-----------------------------------------------------------------------------
00280 // Add a subcurve to the right of an event point.
00281 //
00282 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc>
00283 bool Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_add_curve_to_right
00284     (Event* event, Subcurve* curve,
00285      bool overlap_exist)
00286 {
00287   Event_subcurve_iterator iter;
00288   
00289   for (iter = event->right_curves_begin();
00290        iter != event->right_curves_end();
00291        ++iter)
00292   {
00293     if ((curve == *iter) || (*iter)->is_inner_node(curve))
00294     {
00295       return false;
00296     }
00297     if((curve)->is_inner_node(*iter))
00298     {
00299       *iter = curve;
00300       return false;
00301     }
00302     
00303     if((curve)->has_common_leaf(*iter))
00304     {
00305       std::list<Base_subcurve*>  list_of_sc;
00306       curve->distinct_nodes(*iter, std::back_inserter(list_of_sc));
00307 
00308       typename std::list<Base_subcurve*>::iterator  sc_iter;
00309       for(sc_iter = list_of_sc.begin();
00310           sc_iter != list_of_sc.end();
00311           ++sc_iter)
00312       {
00313         _add_curve_to_right(event, static_cast<Subcurve*>(*sc_iter));
00314       }
00315       return true;
00316     }
00317   }
00318   std::pair<bool, Event_subcurve_iterator> pair_res = 
00319     event->add_curve_to_right(curve, this->m_traits);
00320 
00321   if (! pair_res.first)
00322     // No overlap occurs:
00323     return (false);
00324   
00325   _handle_overlap(event, curve, pair_res.second, overlap_exist);
00326 
00327   // Inidicate that an overlap has occured:
00328   return (true);
00329 }
00330 
00331 //-----------------------------------------------------------------------------
00332 // Remove a curve from the status line.
00333 //
00334 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc>
00335 void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::
00336 _remove_curve_from_status_line (Subcurve *leftCurve,
00337                                 bool remove_for_good)
00338                               
00339 {
00340   CGAL_PRINT("remove_curve_from_status_line\n";);
00341   CGAL_SL_DEBUG(this->PrintStatusLine(););
00342   CGAL_SL_DEBUG(leftCurve->Print(););
00343 
00344   Status_line_iterator sliter = leftCurve->hint(); 
00345   this->m_status_line_insert_hint = sliter; 
00346   ++(this->m_status_line_insert_hint); 
00347 
00348   if(! remove_for_good)
00349   {
00350     // the subcurve is not removed for good, so we dont need to intersect
00351     // his neighbours after its removal.
00352     this->m_statusLine.erase(sliter);
00353     CGAL_PRINT("remove_curve_from_status_line Done\n";)
00354     return;
00355   }
00356 
00357   // the subcurve will be removed for good from the stauts line, we need
00358   // to check for intersection between his two neighbours (below and above him)
00359   // but we need to make sure that its not the first or last subcurve 
00360   // at the status line.
00361   CGAL_assertion(sliter != this->m_statusLine.end());
00362   Status_line_iterator lastOne = this->m_statusLine.end();
00363   --lastOne;
00364 
00365   if (sliter != this->m_statusLine.begin() && sliter != lastOne) 
00366   {
00367     Status_line_iterator prev = sliter; --prev;
00368     Status_line_iterator next = sliter; ++next;
00369     
00370     // intersect *next with  *prev 
00371     _intersect(static_cast<Subcurve*>(*prev),
00372                static_cast<Subcurve*>(*next));
00373   }
00374   this->m_statusLine.erase(sliter);
00375   CGAL_PRINT("remove_curve_from_status_line Done\n";)
00376 } 
00377 
00378 //-----------------------------------------------------------------------------
00379 // Compute intersections between the two given curves.
00380 //
00381 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc>
00382 void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::
00383 _intersect (Subcurve *c1, Subcurve *c2)
00384 {
00385   CGAL_PRINT("Looking for intersection between:\n\t";)
00386   CGAL_SL_DEBUG(c1->Print();)
00387   CGAL_PRINT("\t";)
00388   CGAL_SL_DEBUG(c2->Print();)
00389   CGAL_PRINT("\n";)
00390 
00391   CGAL_assertion(c1 != c2);
00392   
00393   // look up for (c1,c2) in the table and insert if doesnt exist
00394   Curve_pair cv_pair(c1,c2);
00395   if(! (m_curves_pair_set.insert(cv_pair)).second )
00396     return;  //the curves have already been checked for intersection
00397 
00398   float load_factor = static_cast<float>(m_curves_pair_set.size()) /
00399                       m_curves_pair_set.bucket_count();
00400   // after lot of benchemarks, keeping load_factor<=6 is optimal
00401   if(load_factor > 6.0f)
00402     m_curves_pair_set.resize(m_curves_pair_set.size() * 6);
00403 
00404   vector_inserter vi (m_x_objects) ;
00405   vector_inserter vi_end (m_x_objects);
00406   vi_end = this->m_traits->intersect_2_object()(c1->last_curve(),
00407                                                 c2->last_curve(),
00408                                                 vi);
00409 
00410   if (vi == vi_end)
00411   {
00412     CGAL_PRINT("no intersection...\n";);
00413     return; // no intersection at all
00414   }
00415   
00416   // The two subCurves may start at the same point, in that case we ignore the
00417   // first intersection point (if we got to that stage, they cannot  overlap).
00418   if (reinterpret_cast<Event*>(c1->left_event()) == this->m_currentEvent &&
00419       reinterpret_cast<Event*>(c2->left_event()) == this->m_currentEvent)
00420   {
00421     CGAL_PRINT(" [Skipping common left endpoint...]\n";);
00422     ++vi;
00423   }
00424   else
00425   {
00426     // In case both left curve-ends have boundary conditions and are not
00427     // open, check whether the left endpoints are the same. If they are,
00428     // skip the first intersection point.
00429     const Arr_parameter_space   ps_x1 =
00430       this->m_traits->parameter_space_in_x_2_object()(c1->last_curve(),
00431                                                       ARR_MIN_END);
00432     const Arr_parameter_space   ps_y1 =
00433       this->m_traits->parameter_space_in_y_2_object()(c1->last_curve(),
00434                                                       ARR_MIN_END);
00435     const Arr_parameter_space   ps_x2 =
00436       this->m_traits->parameter_space_in_x_2_object()(c2->last_curve(),
00437                                                       ARR_MIN_END);
00438     const Arr_parameter_space   ps_y2 =
00439       this->m_traits->parameter_space_in_y_2_object()(c2->last_curve(),
00440                                                       ARR_MIN_END);
00441 
00442     if ((ps_x1 == ps_x2) && (ps_y1 == ps_y2) &&
00443         ((ps_x1 != ARR_INTERIOR) || (ps_y2 != ARR_INTERIOR)) &&
00444         this->m_traits->is_closed_2_object()(c1->last_curve(), ARR_MIN_END) &&
00445         this->m_traits->is_closed_2_object()(c2->last_curve(), ARR_MIN_END))
00446     {
00447       if (this->m_traits->equal_2_object()
00448           (this->m_traits->construct_min_vertex_2_object() (c1->last_curve()),
00449            this->m_traits->construct_min_vertex_2_object() (c2->last_curve())))
00450       {
00451         CGAL_PRINT(" [Skipping common left endpoint on boundary ...]\n";);
00452         ++vi;
00453       }
00454     }
00455   }
00456 
00457   // If the two subcurves have a common right-event, and the last intersection
00458   // object is a point, we can ignore last intersection (note that in case of
00459   // an overlap that ends at the common endpoint, we definately want to keep
00460   // the intersection object).
00461   if (reinterpret_cast<Event*>(c1->right_event()) ==
00462       reinterpret_cast<Event*>(c2->right_event()))
00463   {
00464     vector_inserter                         vi_last = vi_end;
00465 
00466     --vi_last;
00467     if (object_cast<std::pair<Point_2,unsigned int> > (&(*vi_last)) != NULL)
00468     {
00469       CGAL_PRINT(" [Skipping common right endpoint...]\n";);
00470       --vi_end;
00471     }
00472   }
00473   else
00474   {
00475     // In case both right curve-ends have boundary conditions and are not
00476     // open, check whether the right endpoints are the same. If they are,
00477     // skip the last intersection point.
00478     const Arr_parameter_space   ps_x1 =
00479         this->m_traits->parameter_space_in_x_2_object()(c1->last_curve(),
00480                                                         ARR_MAX_END);
00481     const Arr_parameter_space   ps_y1 =
00482         this->m_traits->parameter_space_in_y_2_object()(c1->last_curve(),
00483                                                         ARR_MAX_END);
00484     const Arr_parameter_space   ps_x2 =
00485         this->m_traits->parameter_space_in_x_2_object()(c2->last_curve(),
00486                                                         ARR_MAX_END);
00487     const Arr_parameter_space   ps_y2 =
00488         this->m_traits->parameter_space_in_y_2_object()(c2->last_curve(),
00489                                                         ARR_MAX_END);
00490 
00491     if ((ps_x1 == ps_x2) && (ps_y1 == ps_y2) &&
00492         ((ps_x1 != ARR_INTERIOR) || (ps_y2 != ARR_INTERIOR)) &&
00493         this->m_traits->is_closed_2_object()(c1->last_curve(), ARR_MAX_END) &&
00494         this->m_traits->is_closed_2_object()(c2->last_curve(), ARR_MAX_END))
00495     {
00496       if (this->m_traits->equal_2_object()
00497           (this->m_traits->construct_max_vertex_2_object() (c1->last_curve()),
00498            this->m_traits->construct_max_vertex_2_object() (c2->last_curve())))
00499       {
00500         vector_inserter                         vi_last = vi_end;
00501 
00502         --vi_last;
00503         if (object_cast<std::pair<Point_2,unsigned int> > (&(*vi_last)) != NULL)
00504         {
00505           CGAL_PRINT(" [Skipping common right endpoint on boundary...]\n";);
00506           --vi_end;
00507         }
00508       }
00509     }
00510   }
00511 
00512   const std::pair<Point_2,unsigned int>  *xp_point;
00513 
00514   if(vi != vi_end)
00515   {
00516     xp_point = object_cast<std::pair<Point_2,unsigned int> > (&(*vi));
00517     if (xp_point != NULL)
00518     {
00519       // Skip the intersection point if it is not larger than the current
00520       // event.
00521       if (this->m_queueEventLess (xp_point->first, this->m_currentEvent) !=
00522           LARGER)
00523       {
00524         ++vi;
00525       }
00526     }
00527   }
00528 
00529   for( ; vi != vi_end ; ++vi)
00530   {
00531     const X_monotone_curve_2 *icv;
00532     Point_2                   xp;
00533     unsigned int              multiplicity = 0;
00534 
00535     xp_point = object_cast<std::pair<Point_2,unsigned int> > (&(*vi));
00536     if (xp_point != NULL)
00537     {
00538       xp = xp_point->first;
00539       multiplicity = xp_point->second;
00540       CGAL_PRINT("found an intersection point: " << xp << "\n";);
00541       _create_intersection_point(xp, multiplicity, c1, c2);
00542     }
00543     else
00544     {
00545       icv = object_cast<X_monotone_curve_2> (&(*vi));
00546       CGAL_assertion (icv != NULL);
00547 
00548       Point_2 left_xp = this->m_traits->construct_min_vertex_2_object()(*icv);
00549       xp = this->m_traits->construct_max_vertex_2_object()(*icv);
00550       
00551       sub_cv1 = *icv;
00552       _create_intersection_point(xp, 0 , c1 , c2);
00553       _create_intersection_point(left_xp, 0 , c1 ,c2, true);
00554     } 
00555   }
00556 }
00557 
00558 //-----------------------------------------------------------------------------
00559 // Create an intersection-point event between two curves.
00560 //
00561 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc>
00562 void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::
00563 _create_intersection_point (const Point_2& xp,
00564                             unsigned int multiplicity,
00565                             Subcurve* &c1, Subcurve* &c2,
00566                             bool is_overlap)
00567 {
00568   // insert the event and check if an event at this point already exists.   
00569   const std::pair<Event*, bool>& pair_res = 
00570     _push_event (xp, Base_event::DEFAULT,
00571                  ARR_INTERIOR, ARR_INTERIOR);
00572     
00573   Event *e = pair_res.first;
00574   if(pair_res.second)    
00575   {                                   
00576     // a new event is creatd , which inidicates 
00577     // that the intersection point cannot be one 
00578     //of the end-points of two curves
00579     
00580     e->set_intersection();
00581     
00582     this->m_visitor ->update_event(e, c1, c2, true);
00583     e->push_back_curve_to_left(c1);
00584     e->push_back_curve_to_left(c2);
00585     
00586     // Act according to the multiplicity:
00587     if (multiplicity == 0)
00588     {
00589       // The multiplicity of the intersection point is unkown or undefined:
00590       _add_curve_to_right(e, c1, is_overlap);
00591       _add_curve_to_right(e, c2, is_overlap);
00592       if(! is_overlap)
00593       {
00594         if(e->is_right_curve_bigger(c1, c2))
00595           std::swap(c1, c2);
00596       }
00597     }
00598     else
00599     {
00600       if((multiplicity % 2) == 1)
00601       {
00602         // The mutiplicity of the intersection point is odd: Swap their
00603         // order to the right of this point.
00604         std::swap(c1,c2);
00605         e->add_curve_pair_to_right (c1, c2);
00606       }
00607       else
00608       {
00609         // The mutiplicity of the intersection point is even, so they
00610         // maintain their order to the right of this point.
00611         CGAL_assertion((multiplicity % 2) == 0);
00612         e->add_curve_pair_to_right (c1, c2);
00613       }
00614     }
00615   } 
00616   else   // the event already exists, so we need to update it accordingly
00617   {
00618     CGAL_PRINT("event already exists,updating.. (" << xp <<")\n";);
00619     if (e == this->m_currentEvent)
00620     {
00621       // This can happen when c1 starts at the interior of c2 (or vice versa).
00622       return;
00623     }
00624     
00625     e->add_curve_to_left(c1);
00626     e->add_curve_to_left(c2); 
00627 
00628     if ( !c1->is_end_point(e) && !c2->is_end_point(e))
00629     {
00630       _add_curve_to_right(e, c1, is_overlap);
00631       _add_curve_to_right(e, c2, is_overlap);
00632       e->set_intersection();
00633       this->m_visitor ->update_event(e, c1, c2, false);
00634     }
00635     else
00636     {
00637       if(!c1->is_end_point(e) && c2->is_end_point(e))
00638       {
00639         _add_curve_to_right(e, c1, is_overlap);
00640         e->set_weak_intersection();
00641         this->m_visitor ->update_event(e, c1);
00642       }
00643       else
00644       {
00645         if(c1->is_end_point(e) && !c2->is_end_point(e))
00646         {
00647           _add_curve_to_right(e, c2, is_overlap);
00648           e->set_weak_intersection();
00649           this->m_visitor ->update_event(e, c2);
00650         }
00651       }
00652     }
00653     if (! is_overlap)
00654     {
00655       if(e->is_right_curve_bigger(c1, c2))
00656         std::swap(c1, c2);
00657     }
00658     
00659     CGAL_SL_DEBUG(e->Print();)
00660   }
00661 }
00662 
00663 //-----------------------------------------------------------------------------
00664 // Fix overlap Subcurves before handling the current event.
00665 //
00666 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc>
00667 void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_fix_overlap_subcurves ()
00668 {
00669   CGAL_assertion(this->m_currentEvent->has_left_curves());
00670   
00671   Event_subcurve_iterator leftCurveIter = 
00672     this->m_currentEvent->left_curves_begin();
00673 
00674   //special treatment for Subcuves that store overlaps
00675   while ( leftCurveIter != this->m_currentEvent->left_curves_end() )  
00676   {
00677     Subcurve *leftCurve = *leftCurveIter;
00678   
00679     // we check if the subcurve store overlap and current event is its
00680     // right end point.
00681     if((Event*)leftCurve->right_event() == this->m_currentEvent)
00682     {
00683       if(leftCurve->originating_subcurve1() != NULL)
00684       {
00685         Subcurve* orig_sc_1 = (Subcurve*)leftCurve->originating_subcurve1();
00686         Subcurve* orig_sc_2 = (Subcurve*)leftCurve->originating_subcurve2();
00687 
00688         _fix_finished_overlap_subcurve(orig_sc_1);
00689         _fix_finished_overlap_subcurve(orig_sc_2);
00690       }
00691     }     
00692     ++leftCurveIter;
00693   }
00694 }
00695 
00696 //-----------------------------------------------------------------------------
00697 // Handle overlap at right insertion to event.
00698 // event - the event where that overlap starts (the left
00699 // end point of the overlap).
00700 // curve - the subcurve that its insertion to the list of right subcurves of
00701 // 'event' causes the overlap (with *iter).
00702 // iter - the existing subcurve at the right subcurves of 'event'
00703 // overlap_exist - a flag indicates if the overlap X_monotone_curve_2 was
00704 // computed already (is true than its stored at sub_cv1 data member).
00705 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc>
00706 void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::_handle_overlap
00707     (Event* event,
00708      Subcurve* curve,
00709      Event_subcurve_iterator iter,
00710      bool overlap_exist)
00711 {
00712   // An overlap occurs:
00713   CGAL_PRINT("Overlap detected at right insertion...\n";);
00714   
00715   X_monotone_curve_2 overlap_cv;
00716   if(overlap_exist)
00717     overlap_cv = sub_cv1;
00718   else
00719   {
00720     // compute the overlap.
00721     std::vector<Object>  obj_vec; 
00722     vector_inserter vit(obj_vec);
00723     this->m_traits->intersect_2_object()(curve->last_curve(),
00724                                          (*iter)->last_curve(),
00725                                          vit);
00726 
00727     if(obj_vec.empty())
00728       return;
00729 
00730     overlap_cv = object_cast<X_monotone_curve_2> (obj_vec.front());
00731   }
00732 
00733    
00734   // Get the right end of overlap_cv (if it is closed from the right).
00735   Event         *right_end;
00736   Arr_parameter_space  ps_x_r =
00737     this->m_traits->parameter_space_in_x_2_object()(overlap_cv, ARR_MAX_END);
00738   Arr_parameter_space  ps_y_r =
00739     this->m_traits->parameter_space_in_y_2_object()(overlap_cv, ARR_MAX_END);
00740 
00741   CGAL_assertion (ps_x_r != ARR_LEFT_BOUNDARY);
00742   if (ps_x_r != ARR_INTERIOR || ps_y_r != ARR_INTERIOR)
00743   {
00744     // The overlapping subcurve is either open from the right, or
00745     // touches the boundary of the surface. In either case, the curves that
00746     // are involved in the overlap must also be open or defined at the
00747     // boundary, so the event associated with their right ends already exists,
00748     // and we set it as the overlapping subcurve's right event.
00749     CGAL_assertion((*iter)->right_event() == curve->right_event());
00750     right_end = (Event*)(curve->right_event());
00751   }
00752   else
00753   {
00754     // The overlapping subcurve has a valid right endpoint.
00755     // Find the event associated with this point (or create a new event).
00756     Point_2 end_overlap =
00757       this->m_traits->construct_max_vertex_2_object()(overlap_cv);
00758 
00759     const std::pair<Event*, bool>& pair_res =
00760       _push_event (end_overlap, Base_event::OVERLAP, ps_x_r, ps_y_r);
00761 
00762     right_end = pair_res.first;
00763   }
00764 
00765   // Get the left end of overlap_cv (if it is closed from the left).
00766   Arr_parameter_space  ps_x_l =
00767     this->m_traits->parameter_space_in_x_2_object()(overlap_cv, ARR_MIN_END);
00768   Arr_parameter_space  ps_y_l =
00769     this->m_traits->parameter_space_in_y_2_object()(overlap_cv, ARR_MIN_END);
00770   
00771   CGAL_assertion (ps_x_l != ARR_RIGHT_BOUNDARY);
00772   if (ps_x_l == ARR_INTERIOR && ps_y_l == ARR_INTERIOR)
00773   {
00774     // The left end of the overlapping subcurve is regular point, so in case
00775     // the event is also associated with a regular point (not incident to the
00776     // surface boundaries), we make sure that the overlapping subcurve does
00777     // not start to the left of this event.
00778     if (! event->is_on_boundary())
00779     {
00780       // If the left endpoint of the overlapping curve is to the left of the
00781       // event, split the overlapping subcurve so its left endpoint equals
00782       // the event point.
00783       const Point_2&     begin_overlap =
00784         this->m_traits->construct_min_vertex_2_object()(overlap_cv);
00785       Comparison_result  res =
00786         this->m_traits->compare_xy_2_object() (event->point(), begin_overlap);
00787 
00788       CGAL_assertion (res != SMALLER);
00789       if (res == LARGER)
00790       {
00791         this->m_traits->split_2_object() (overlap_cv, event->point(),
00792                                           sub_cv1, sub_cv2);
00793         overlap_cv = sub_cv2;
00794       }
00795     }
00796   }
00797   else
00798   {
00799     // The left end of the overlapping subcurve is either open, or
00800     // incident to the surface boundaries. In case the current event is
00801     // associated with a regular point, it must lie to the right of this
00802     // curve-end, so we clip the overlapping subcurve accordingly.
00803     if (! event->is_on_boundary())
00804     {
00805       this->m_traits->split_2_object() (overlap_cv, event->point(),
00806                                         sub_cv1, sub_cv2);
00807       overlap_cv = sub_cv2;
00808     }
00809   }
00810 
00811   // Alocate a new Subcure for the overlap
00812   Subcurve *overlap_sc = this->m_subCurveAlloc.allocate(1);
00813   this->m_subCurveAlloc.construct(overlap_sc, this->m_masterSubcurve);
00814   overlap_sc->init(overlap_cv);
00815   overlap_sc->set_left_event(event);
00816   overlap_sc->set_right_event(right_end);
00817   m_overlap_subCurves.push_back(overlap_sc);
00818 
00819   CGAL_PRINT(curve<<" + " <<*iter<<" => " <<overlap_sc<<"\n");
00820   // Set the two events' attribute to overlap.
00821   event -> set_overlap();
00822   //right_end -> set_overlap();
00823   
00824   // Remove curve, *iter from the left curves of end_overlap event
00825   right_end->remove_curve_from_left(curve);
00826   right_end->remove_curve_from_left(*iter);
00827   
00828   // Add overlap_sc to the left curves
00829   right_end->add_curve_to_left(overlap_sc);
00830   
00831   // sets the two originating subcurves of overlap_sc
00832   overlap_sc -> set_originating_subcurve1(*iter);
00833   overlap_sc -> set_originating_subcurve2(curve);  
00834 
00835   // If one of the originating subcurves (or both), does not end
00836   // at the right end of the overlap, add them to the right subcurves
00837   // of the event associated with the right end of the overlap.
00838   if((Event*)curve->right_event() != right_end)
00839   {
00840     _add_curve_to_right(right_end, curve);
00841   }
00842   
00843   if((Event*)(*iter)->right_event() != right_end)
00844   {
00845     _add_curve_to_right(right_end, (*iter));
00846   }
00847 
00848   this->m_visitor->found_overlap(curve, *iter, overlap_sc);
00849   
00850   // Replace current sub-curve (*iter) with the new sub-curve
00851   (*iter) = overlap_sc;
00852 }
00853 
00854 //-----------------------------------------------------------------------------
00855 // Fix a subcurve that represents an overlap.
00856 // sc - some originating subcurve of a aubcurve that stores an overlap
00857 // notice thah this function is recursive since an originating subcurve of 
00858 // an overlap can be itself a subcurve that stores overlap and so on.
00859 template <class Tr, class Vis, class Subcv, class Evnt, typename Alloc>
00860 void Sweep_line_2<Tr, Vis, Subcv, Evnt, Alloc>::
00861 _fix_finished_overlap_subcurve (Subcurve* sc)
00862 {
00863   //
00864   CGAL_assertion(sc != NULL);
00865 
00866   // split 'sc' if necessary and update to event as weak intersection
00867   if((Event*)sc->right_event() != this->m_currentEvent)
00868   {
00869     this->m_traits->split_2_object() (sc->last_curve(),
00870                                       this->m_currentEvent->point(),
00871                                       sub_cv1, sub_cv2);
00872     sc->set_last_curve(sub_cv2);
00873     
00874     this->m_currentEvent->set_weak_intersection();
00875     this->m_visitor ->update_event(this->m_currentEvent,(Subcurve*)sc);
00876     return;
00877   }
00878 
00879   if(!sc->originating_subcurve1())
00880     // sc does not store an overlap, we are done
00881     return;
00882 
00883   // sc is a subcurve that stores overlap, we have to continue with the 
00884   // recursion and deal with his two originating subcurves recursively.
00885   Subcurve* orig_sc_1 = (Subcurve*)sc->originating_subcurve1();
00886   Subcurve* orig_sc_2 = (Subcurve*)sc->originating_subcurve2();
00887 
00888   _fix_finished_overlap_subcurve(orig_sc_1);
00889   _fix_finished_overlap_subcurve(orig_sc_2);
00890 }
00891 
00892 CGAL_END_NAMESPACE
00893 
00894 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines