BWAPI
|
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