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/Arr_overlay_traits_2.h $ 00015 // $Id: Arr_overlay_traits_2.h 50366 2009-07-05 12:56:48Z efif $ 00016 // 00017 // 00018 // Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il> 00019 // Ron Wein <wein@post.tau.ac.il> 00020 // Efi Fogel <efif@post.tau.ac.il> 00021 00022 #ifndef CGAL_ARR_OVERLAY_TRAITS_2_H 00023 #define CGAL_ARR_OVERLAY_TRAITS_2_H 00024 00029 #include <CGAL/Object.h> 00030 #include <CGAL/Arr_tags.h> 00031 00032 CGAL_BEGIN_NAMESPACE 00033 00040 template <typename Traits_, 00041 typename ArrangementRed_, 00042 typename ArrangementBlue_> 00043 class Arr_overlay_traits_2 00044 { 00045 public: 00046 00047 typedef Traits_ Traits_2; 00048 typedef ArrangementRed_ Arrangement_red_2; 00049 typedef ArrangementBlue_ Arrangement_blue_2; 00050 00051 typedef typename Arrangement_red_2::Face_const_handle 00052 Face_handle_red; 00053 typedef typename Arrangement_blue_2::Face_const_handle 00054 Face_handle_blue; 00055 00056 typedef typename Arrangement_red_2::Halfedge_const_handle 00057 Halfedge_handle_red; 00058 typedef typename Arrangement_blue_2::Halfedge_const_handle 00059 Halfedge_handle_blue; 00060 00061 typedef typename Arrangement_red_2::Vertex_const_handle 00062 Vertex_handle_red; 00063 typedef typename Arrangement_blue_2::Vertex_const_handle 00064 Vertex_handle_blue; 00065 00066 typedef typename Traits_2::X_monotone_curve_2 Base_x_monotone_curve_2; 00067 typedef typename Traits_2::Point_2 Base_point_2; 00068 00069 typedef typename Traits_2::Compare_x_2 Base_compare_x_2; 00070 typedef typename Traits_2::Compare_xy_2 Base_compare_xy_2; 00071 typedef typename Traits_2::Construct_min_vertex_2 Base_construct_min_vertex_2; 00072 typedef typename Traits_2::Construct_max_vertex_2 Base_construct_max_vertex_2; 00073 typedef typename Traits_2::Is_vertical_2 Base_is_vertical_2; 00074 typedef typename Traits_2::Compare_y_at_x_2 Base_compare_y_at_x_2; 00075 typedef typename Traits_2::Compare_y_at_x_right_2 Base_compare_y_at_x_right_2; 00076 typedef typename Traits_2::Intersect_2 Base_intersect_2; 00077 typedef typename Traits_2::Split_2 Base_split_2; 00078 typedef typename Traits_2::Equal_2 Base_equal_2; 00079 00080 typedef typename CGALi::Arr_complete_left_side_tag< Traits_2 >::Tag 00081 Arr_left_side_tag; 00082 typedef typename CGALi::Arr_complete_bottom_side_tag< Traits_2 >::Tag 00083 Arr_bottom_side_tag; 00084 typedef typename CGALi::Arr_complete_top_side_tag< Traits_2 >::Tag 00085 Arr_top_side_tag; 00086 typedef typename CGALi::Arr_complete_right_side_tag< Traits_2 >::Tag 00087 Arr_right_side_tag; 00088 00089 /* Overlay is implemented as sweep-line visitor. The sweep-line algorithm 00090 * never uses Compare_y_at_x_left_2, and it never performs merging of curves. 00091 * Thus, AreMergeable_2 and Merge_2 are not needed either. 00092 */ 00093 typedef Tag_false Has_left_category; 00094 typedef Tag_false Has_merge_category; 00095 00096 // The color of a feature. 00097 enum Color 00098 { 00099 RED, // From the "red" arrangement. 00100 BLUE, // From the "blue" arrangement. 00101 RB_OVERLAP // Red-blue overlap. 00102 }; 00103 00104 private: 00105 00106 const Traits_2 * m_base_traits; // The base traits object. 00107 00108 public: 00109 00111 Arr_overlay_traits_2() 00112 {} 00113 00115 Arr_overlay_traits_2 (const Traits_2 & base_tr) : 00116 m_base_traits (&base_tr) 00117 {} 00118 00119 const Traits_2 * base_traits() const { return m_base_traits; } 00120 00124 class Ex_x_monotone_curve_2 00125 { 00126 public: 00127 00128 typedef Base_x_monotone_curve_2 Base; 00129 00130 protected: 00131 00132 Base m_base_xcv; // The base curve. 00133 Halfedge_handle_red m_red_halfedge_handle; // The red halfedge. 00134 Halfedge_handle_blue m_blue_halfedge_handle; // The blue halfedge. 00135 00136 public: 00137 00139 Ex_x_monotone_curve_2() : 00140 m_base_xcv(), 00141 m_red_halfedge_handle(), 00142 m_blue_halfedge_handle() 00143 {} 00144 00146 Ex_x_monotone_curve_2 (const Base& xcv): 00147 m_base_xcv(xcv), 00148 m_red_halfedge_handle(), 00149 m_blue_halfedge_handle() 00150 {} 00151 00153 Ex_x_monotone_curve_2 (const Base& xcv, 00154 Halfedge_handle_red he_r, 00155 Halfedge_handle_blue he_b): 00156 m_base_xcv(xcv), 00157 m_red_halfedge_handle (he_r), 00158 m_blue_halfedge_handle (he_b) 00159 { 00160 CGAL_precondition (he_r == Halfedge_handle_red() || 00161 he_r->direction() == ARR_RIGHT_TO_LEFT); 00162 CGAL_precondition (he_b == Halfedge_handle_blue() || 00163 he_b->direction() == ARR_RIGHT_TO_LEFT); 00164 } 00165 00167 const Base& base () const 00168 { 00169 return (m_base_xcv); 00170 } 00171 00173 Base& base () 00174 { 00175 return (m_base_xcv); 00176 } 00177 00179 operator const Base& () const 00180 { 00181 return (m_base_xcv); 00182 } 00183 00185 operator Base&() 00186 { 00187 return (m_base_xcv); 00188 } 00189 00191 Halfedge_handle_red red_halfedge_handle() const 00192 { 00193 return (m_red_halfedge_handle); 00194 } 00195 00197 Halfedge_handle_blue blue_halfedge_handle() const 00198 { 00199 return (m_blue_halfedge_handle); 00200 } 00201 00203 void set_red_halfedge_handle (Halfedge_handle_red he_r) 00204 { 00205 CGAL_precondition (he_r == Halfedge_handle_red() || 00206 he_r->direction() == ARR_RIGHT_TO_LEFT); 00207 00208 m_red_halfedge_handle = he_r; 00209 } 00210 00212 void set_blue_halfedge_handle (Halfedge_handle_blue he_b) 00213 { 00214 CGAL_precondition (he_b == Halfedge_handle_blue() || 00215 he_b->direction() == ARR_RIGHT_TO_LEFT); 00216 00217 m_blue_halfedge_handle = he_b; 00218 } 00219 00221 Color color () const 00222 { 00223 Halfedge_handle_red null_red_he; 00224 Halfedge_handle_blue null_blue_he; 00225 00226 if (m_red_halfedge_handle != null_red_he && 00227 m_blue_halfedge_handle == null_blue_he) 00228 return (RED); 00229 00230 if (m_blue_halfedge_handle != null_blue_he && 00231 m_red_halfedge_handle == null_red_he) 00232 return (BLUE); 00233 00234 // Overlap, return the RB_OVERLAP color: 00235 CGAL_assertion (m_red_halfedge_handle != null_red_he && 00236 m_blue_halfedge_handle != null_blue_he); 00237 return (RB_OVERLAP); 00238 } 00239 00240 }; // nested class Ex_x_monotone_curve_2 - END 00241 00242 typedef Ex_x_monotone_curve_2 X_monotone_curve_2; 00243 00244 #ifdef CGAL_SL_VERBOSE 00245 // For debugging purposes: 00246 friend std::ostream& operator<< (std::ostream& os, 00247 const X_monotone_curve_2& xcv) 00248 { 00249 os << xcv.base(); 00250 return (os); 00251 } 00252 #endif 00253 00257 class Ex_point_2 00258 { 00259 public: 00260 00261 typedef Base_point_2 Base; 00262 00263 protected: 00264 00265 Base m_base_pt; // The base point. 00266 Object m_red_obj; // The "red" object. 00267 Object m_blue_obj; // The "blue" object. 00268 00269 public: 00270 00272 Ex_point_2() : 00273 m_base_pt(), 00274 m_red_obj(), 00275 m_blue_obj() 00276 {} 00277 00279 Ex_point_2 (const Base& pt) : 00280 m_base_pt (pt), 00281 m_red_obj(), 00282 m_blue_obj() 00283 {} 00284 00286 Ex_point_2 (const Base& pt, const Object& obj_r, const Object& obj_b) : 00287 m_base_pt (pt), 00288 m_red_obj (obj_r), 00289 m_blue_obj (obj_b) 00290 {} 00291 00293 const Base& base () const 00294 { 00295 return (m_base_pt); 00296 } 00297 00299 Base& base () 00300 { 00301 return (m_base_pt); 00302 } 00303 00305 operator const Base& () const 00306 { 00307 return (m_base_pt); 00308 } 00309 00311 operator Base& () 00312 { 00313 return (m_base_pt); 00314 } 00315 00317 const Object& red_object() const 00318 { 00319 return (m_red_obj); 00320 } 00321 00323 const Object& blue_object() const 00324 { 00325 return (m_blue_obj); 00326 } 00327 00329 bool is_red_object_empty () const 00330 { 00331 return (m_red_obj.is_empty()); 00332 } 00333 00335 bool is_blue_object_empty () const 00336 { 00337 return (m_blue_obj.is_empty()); 00338 } 00339 00341 void set_red_object (const Object& obj_r) 00342 { 00343 m_red_obj = obj_r; 00344 } 00345 00347 void set_blue_object (const Object& obj_b) 00348 { 00349 m_blue_obj = obj_b; 00350 } 00351 00352 }; 00353 00354 typedef Ex_point_2 Point_2; 00355 00356 #ifdef CGAL_SL_VERBOSE 00357 // For debugging purposes: 00358 friend std::ostream& operator<< (std::ostream& os, 00359 const Point_2& pt) 00360 { 00361 os << pt.base(); 00362 return (os); 00363 } 00364 #endif 00365 00367 class Intersect_2 { 00368 protected: 00370 const Arr_overlay_traits_2 * m_traits; 00371 00377 Intersect_2(const Arr_overlay_traits_2 * traits) : m_traits(traits) {} 00378 00380 friend class Arr_overlay_traits_2<Traits_2, 00381 Arrangement_red_2, 00382 Arrangement_blue_2>; 00383 00384 public: 00385 template<class OutputIterator> 00386 OutputIterator operator() (const X_monotone_curve_2 & xcv1, 00387 const X_monotone_curve_2 & xcv2, 00388 OutputIterator oi) 00389 { 00390 // In case the curves originate from the same arrangement, they are 00391 // obviously interior-disjoint. 00392 if (xcv1.color() == xcv2.color()) 00393 return (oi); 00394 00395 if (xcv1.color() == RB_OVERLAP || xcv2.color() == RB_OVERLAP) 00396 return (oi); 00397 00398 // Compute the intersection points between the curves. Note that if 00399 // xcv1 and xcv2 are subcruves of x-monotone curves that had intersected 00400 // before the current point on the status line, we may get a filter 00401 // failure if we send the subcurve whose left endpoint is to the left 00402 // of the other curve - this is because their previously computed 00403 // intersection point p may be equal to the this left endpoint. As many 00404 // traits classes start by computing the intersection between the 00405 // supporting curves and then check whether the result is in the x-range 00406 // of both subcurves, this will result in a filter failure. However, if 00407 // we send xcv1 first, then p is obviusly not in its x-range and there is 00408 // no filter failure. 00409 // 00410 // / xcv1 00411 // / 00412 // / 00413 // ----+-- 00414 // / 00415 // / 00416 // p +------------- xcv2 00417 // ^ 00418 // | 00419 // status line 00420 // 00421 // Note that we do not bother with curves whose left ends are open, 00422 // since such curved did not intersect before. 00423 00424 const std::pair<Base_point_2, unsigned int> *base_ipt; 00425 const Base_x_monotone_curve_2 *overlap_xcv; 00426 bool send_xcv1_first = true; 00427 OutputIterator oi_end; 00428 00429 Parameter_space_in_x_2 ps_x_op = 00430 m_traits->parameter_space_in_x_2_object(); 00431 Parameter_space_in_y_2 ps_y_op = 00432 m_traits->parameter_space_in_y_2_object(); 00433 const Arr_parameter_space bx1 = ps_x_op (xcv1, ARR_MIN_END); 00434 const Arr_parameter_space by1 = ps_y_op (xcv1, ARR_MIN_END); 00435 const Arr_parameter_space bx2 = ps_x_op (xcv2, ARR_MIN_END); 00436 const Arr_parameter_space by2 = ps_y_op (xcv2, ARR_MIN_END); 00437 00438 const Traits_2 * m_base_tr = m_traits->base_traits(); 00439 00440 if (bx1 == ARR_INTERIOR && by1 == ARR_INTERIOR && 00441 bx2 == ARR_INTERIOR && by2 == ARR_INTERIOR) 00442 { 00443 send_xcv1_first = 00444 (m_base_tr->compare_xy_2_object() 00445 (m_base_tr->construct_min_vertex_2_object()(xcv1.base()), 00446 m_base_tr->construct_min_vertex_2_object()(xcv2.base())) == LARGER); 00447 } 00448 00449 oi_end = (send_xcv1_first) ? 00450 m_base_tr->intersect_2_object()(xcv1.base(), xcv2.base(), oi) : 00451 m_base_tr->intersect_2_object()(xcv2.base(), xcv1.base(), oi); 00452 00453 // Convert objects that are associated with Base_x_monotone_curve_2 to 00454 // the exteneded X_monotone_curve_2. 00455 for (; oi != oi_end; ++oi) 00456 { 00457 base_ipt = object_cast<std::pair<Base_point_2, unsigned int> >(&(*oi)); 00458 00459 if (base_ipt != NULL) 00460 { 00461 // We have an red-blue intersection point, so we attach the 00462 // intersecting red and blue halfedges to it. 00463 Object red_obj; 00464 Object blue_obj; 00465 00466 if (xcv1.color() == RED) 00467 { 00468 CGAL_assertion (xcv2.color() == BLUE); 00469 red_obj = CGAL::make_object (xcv1.red_halfedge_handle()); 00470 blue_obj = CGAL::make_object (xcv2.blue_halfedge_handle()); 00471 } 00472 else 00473 { 00474 CGAL_assertion(xcv2.color() == RED && 00475 xcv1.color() == BLUE); 00476 red_obj = CGAL::make_object(xcv2.red_halfedge_handle()); 00477 blue_obj = CGAL::make_object(xcv1.blue_halfedge_handle()); 00478 } 00479 00480 // Create the extended point and add the multiplicity. 00481 Point_2 ex_point (base_ipt->first, 00482 red_obj, blue_obj); 00483 *oi = CGAL::make_object(std::make_pair (ex_point, 00484 base_ipt->second)); 00485 } 00486 else 00487 { 00488 overlap_xcv = object_cast<Base_x_monotone_curve_2> (&(*oi)); 00489 CGAL_assertion (overlap_xcv != NULL); 00490 00491 // We have a red-blue overlap, so we mark the curve accordingly. 00492 Halfedge_handle_red red_he; 00493 Halfedge_handle_blue blue_he; 00494 00495 if (xcv1.color() == RED) 00496 { 00497 red_he = xcv1.red_halfedge_handle(); 00498 00499 // Overlap can occur only between curves from a different color. 00500 CGAL_assertion(xcv2.color() == BLUE); 00501 blue_he = xcv2.blue_halfedge_handle(); 00502 } 00503 else 00504 { 00505 CGAL_assertion(xcv1.color() == BLUE && 00506 xcv2.color() == RED); 00507 00508 red_he = xcv2.red_halfedge_handle(); 00509 blue_he = xcv1.blue_halfedge_handle(); 00510 } 00511 00512 *oi = CGAL::make_object (X_monotone_curve_2 (*overlap_xcv, 00513 red_he, blue_he)); 00514 } 00515 } 00516 00517 // Return the past-the-end iterator. 00518 return (oi_end); 00519 } 00520 }; 00521 00523 Intersect_2 intersect_2_object () const 00524 { 00525 return Intersect_2(this); 00526 } 00527 00529 class Split_2 { 00530 protected: 00532 Base_split_2 m_base_split; 00533 00539 Split_2 (const Base_split_2& base) : m_base_split (base) {} 00540 00542 friend class Arr_overlay_traits_2<Traits_2, 00543 Arrangement_red_2, 00544 Arrangement_blue_2>; 00545 00546 public: 00547 void operator() (const X_monotone_curve_2& xcv, const Point_2 & p, 00548 X_monotone_curve_2& c1, X_monotone_curve_2& c2) 00549 { 00550 // Split the base curve. 00551 m_base_split(xcv.base(), p.base(), c1.base(), c2.base()); 00552 00553 // Duplicate the halfedge data to the resulting curves. 00554 c1.set_red_halfedge_handle (xcv.red_halfedge_handle()); 00555 c1.set_blue_halfedge_handle (xcv.blue_halfedge_handle()); 00556 00557 c2.set_red_halfedge_handle (xcv.red_halfedge_handle()); 00558 c2.set_blue_halfedge_handle (xcv.blue_halfedge_handle()); 00559 } 00560 }; 00561 00563 Split_2 split_2_object () const 00564 { 00565 return Split_2(m_base_traits->split_2_object()); 00566 } 00567 00569 class Construct_min_vertex_2 { 00570 protected: 00572 Base_construct_min_vertex_2 m_base_min_v; 00573 Base_equal_2 m_base_equal; 00574 00580 Construct_min_vertex_2 (const Base_construct_min_vertex_2& base_min_v, 00581 const Base_equal_2& base_equal) : 00582 m_base_min_v (base_min_v), 00583 m_base_equal (base_equal) 00584 {} 00585 00587 friend class Arr_overlay_traits_2<Traits_2, 00588 Arrangement_red_2, 00589 Arrangement_blue_2>; 00590 00591 public: 00592 Point_2 operator() (const X_monotone_curve_2& xcv) 00593 { 00594 // Create the objects that wrap the arrangement vertex. 00595 // Note that the halfedges associated with the curves are always 00596 // directed from right to left, so their target is the smaller end. 00597 const Base_point_2& base_p = m_base_min_v (xcv.base()); 00598 Object obj_red, obj_blue; 00599 00600 if (xcv.color() == RED) 00601 { 00602 obj_red = CGAL::make_object (xcv.red_halfedge_handle()->target()); 00603 } 00604 else if (xcv.color() == BLUE) 00605 { 00606 obj_blue = CGAL::make_object (xcv.blue_halfedge_handle()->target()); 00607 } 00608 else 00609 { 00610 CGAL_assertion (xcv.color() == RB_OVERLAP); 00611 00612 if (! xcv.red_halfedge_handle()->target()->is_at_open_boundary() && 00613 m_base_equal (base_p, 00614 xcv.red_halfedge_handle()->target()->point())) 00615 { 00616 obj_red = CGAL::make_object (xcv.red_halfedge_handle()->target()); 00617 } 00618 00619 if (! xcv.blue_halfedge_handle()->target()->is_at_open_boundary() && 00620 m_base_equal (base_p, 00621 xcv.blue_halfedge_handle()->target()->point())) 00622 { 00623 obj_blue = CGAL::make_object (xcv.blue_halfedge_handle()->target()); 00624 } 00625 } 00626 00627 return (Point_2 (base_p, obj_red, obj_blue)); 00628 } 00629 }; 00630 00632 Construct_min_vertex_2 construct_min_vertex_2_object () const 00633 { 00634 return 00635 (Construct_min_vertex_2 (m_base_traits->construct_min_vertex_2_object(), 00636 m_base_traits->equal_2_object())); 00637 } 00638 00640 class Construct_max_vertex_2 { 00641 protected: 00643 Base_construct_max_vertex_2 m_base_max_v; 00644 Base_equal_2 m_base_equal; 00645 00651 Construct_max_vertex_2 (const Base_construct_max_vertex_2& base_max_v, 00652 const Base_equal_2& base_equal) : 00653 m_base_max_v (base_max_v), 00654 m_base_equal (base_equal) 00655 {} 00656 00658 friend class Arr_overlay_traits_2<Traits_2, 00659 Arrangement_red_2, 00660 Arrangement_blue_2>; 00661 00662 public: 00663 Point_2 operator() (const X_monotone_curve_2 & xcv) const 00664 { 00665 // Create the objects that wrap the arrangement vertex. 00666 // Note that the halfedges associated with the curves are always 00667 // directed from right to left, so their target is the smaller end. 00668 const Base_point_2& base_p = m_base_max_v (xcv.base()); 00669 Object obj_red, obj_blue; 00670 00671 if(xcv.color() == RED) 00672 { 00673 obj_red = CGAL::make_object (xcv.red_halfedge_handle()->source()); 00674 } 00675 else if(xcv.color() == BLUE) 00676 { 00677 obj_blue = CGAL::make_object (xcv.blue_halfedge_handle()->source()); 00678 } 00679 else 00680 { 00681 CGAL_assertion(xcv.color() == RB_OVERLAP); 00682 00683 if (! xcv.red_halfedge_handle()->source()->is_at_open_boundary() && 00684 m_base_equal (base_p, 00685 xcv.red_halfedge_handle()->source()->point())) 00686 { 00687 obj_red = CGAL::make_object (xcv.red_halfedge_handle()->source()); 00688 } 00689 00690 if (! xcv.blue_halfedge_handle()->source()->is_at_open_boundary() && 00691 m_base_equal (base_p, 00692 xcv.blue_halfedge_handle()->source()->point())) 00693 { 00694 obj_blue = CGAL::make_object (xcv.blue_halfedge_handle()->source()); 00695 } 00696 } 00697 00698 return (Point_2 (base_p, obj_red, obj_blue)); 00699 } 00700 }; 00701 00703 Construct_max_vertex_2 construct_max_vertex_2_object () const 00704 { 00705 return 00706 (Construct_max_vertex_2 (m_base_traits->construct_max_vertex_2_object(), 00707 m_base_traits->equal_2_object())); 00708 } 00709 00711 class Is_vertical_2 { 00712 protected: 00714 Base_is_vertical_2 m_base_is_vert; 00715 00721 Is_vertical_2 (const Base_is_vertical_2 & base) : m_base_is_vert(base) {} 00722 00724 friend class Arr_overlay_traits_2<Traits_2, 00725 Arrangement_red_2, 00726 Arrangement_blue_2>; 00727 00728 public: 00729 bool operator() (const X_monotone_curve_2 & xcv) const 00730 { 00731 return m_base_is_vert (xcv.base()); 00732 } 00733 }; 00734 00736 Is_vertical_2 is_vertical_2_object () const 00737 { 00738 return Is_vertical_2(m_base_traits->is_vertical_2_object()); 00739 } 00740 00744 class Equal_2 { 00745 protected: 00747 Base_equal_2 m_base_equal; 00748 00754 Equal_2 (const Base_equal_2 & base) : m_base_equal(base) {} 00755 00757 friend class Arr_overlay_traits_2<Traits_2, 00758 Arrangement_red_2, 00759 Arrangement_blue_2>; 00760 00761 public: 00762 bool operator() (const Point_2 & p1, const Point_2 & p2) const 00763 { 00764 return m_base_equal (p1.base(), p2.base()); 00765 } 00766 00767 bool operator() (const X_monotone_curve_2 & xcv1, 00768 const X_monotone_curve_2 & xcv2) const 00769 { 00770 return m_base_equal (xcv1.base(), xcv2.base()); 00771 } 00772 }; 00773 00775 Equal_2 equal_2_object () const 00776 { 00777 return Equal_2(m_base_traits->equal_2_object()); 00778 } 00779 00781 class Compare_x_2 { 00782 protected: 00784 Base_compare_x_2 m_base_cmp_x; 00785 00791 Compare_x_2 (const Base_compare_x_2 & base) : m_base_cmp_x(base) {} 00792 00794 friend class Arr_overlay_traits_2<Traits_2, 00795 Arrangement_red_2, 00796 Arrangement_blue_2>; 00797 00798 public: 00799 Comparison_result operator() (const Point_2 & p1, const Point_2 & p2) const 00800 { 00801 return m_base_cmp_x (p1.base(), p2.base()); 00802 } 00803 }; 00804 00806 Compare_x_2 compare_x_2_object () const 00807 { 00808 return Compare_x_2(m_base_traits->compare_x_2_object()); 00809 } 00810 00812 class Compare_xy_2 { 00813 protected: 00815 Base_compare_xy_2 m_base_cmp_xy; 00816 00822 Compare_xy_2(const Base_compare_xy_2& base) : 00823 m_base_cmp_xy(base) 00824 {} 00825 00827 friend class Arr_overlay_traits_2<Traits_2, 00828 Arrangement_red_2, 00829 Arrangement_blue_2>; 00830 00831 public: 00832 Comparison_result operator() (const Point_2& p1, const Point_2& p2) const 00833 { 00834 // Check if there wither points represent red or blue vertices. 00835 Vertex_handle_red vr1; 00836 Vertex_handle_red vr2; 00837 00838 Vertex_handle_blue vb1; 00839 Vertex_handle_blue vb2; 00840 00841 const bool assign_v1_red = CGAL::assign (vr1, p1.red_object()); 00842 const bool assign_v2_red = CGAL::assign (vr2, p2.red_object()); 00843 const bool assign_v1_blue = CGAL::assign (vb1, p1.blue_object()); 00844 const bool assign_v2_blue = CGAL::assign (vb2, p2.blue_object()); 00845 00846 if ((assign_v1_red && assign_v1_blue) || 00847 (assign_v2_red && assign_v2_blue)) 00848 { 00849 // In case of an overlapping vertex, just perform the comparison. 00850 return (m_base_cmp_xy (p1.base(), p2.base())); 00851 } 00852 00853 // If both points are vertices of the same color, avoid the geometric 00854 // comparison if they refer to the same vertex. 00855 if ((assign_v1_red && assign_v2_red && vr1 == vr2) || 00856 (assign_v1_blue && assign_v2_blue && vb1 == vb2)) 00857 { 00858 return (EQUAL); 00859 } 00860 00861 return (m_base_cmp_xy (p1.base(), p2.base())); 00862 } 00863 }; 00864 00866 Compare_xy_2 compare_xy_2_object () const 00867 { 00868 return (Compare_xy_2(m_base_traits->compare_xy_2_object())); 00869 } 00870 00874 class Compare_y_at_x_2 { 00875 protected: 00877 Base_compare_y_at_x_2 m_base_cmp_y_at_x; 00878 00884 Compare_y_at_x_2(const Base_compare_y_at_x_2& base): 00885 m_base_cmp_y_at_x(base) 00886 {} 00887 00889 friend class Arr_overlay_traits_2<Traits_2, 00890 Arrangement_red_2, 00891 Arrangement_blue_2>; 00892 00893 public: 00894 Comparison_result operator() (const Point_2 & p, 00895 const X_monotone_curve_2 & xcv) const 00896 { 00897 return (m_base_cmp_y_at_x (p.base(), xcv.base())); 00898 } 00899 }; 00900 00902 Compare_y_at_x_2 compare_y_at_x_2_object () const 00903 { 00904 return (Compare_y_at_x_2(m_base_traits->compare_y_at_x_2_object())); 00905 } 00906 00910 class Compare_y_at_x_right_2 { 00911 protected: 00913 Base_compare_y_at_x_right_2 m_base_cmp_y_at_x_right; 00914 00920 Compare_y_at_x_right_2(const Base_compare_y_at_x_right_2& base): 00921 m_base_cmp_y_at_x_right(base) 00922 {} 00923 00925 friend class Arr_overlay_traits_2<Traits_2, 00926 Arrangement_red_2, 00927 Arrangement_blue_2>; 00928 00929 public: 00930 Comparison_result operator() (const X_monotone_curve_2& xcv1, 00931 const X_monotone_curve_2& xcv2, 00932 const Point_2& p) const 00933 { 00934 return (m_base_cmp_y_at_x_right(xcv1.base(), 00935 xcv2.base(), 00936 p.base())); 00937 } 00938 }; 00939 00941 Compare_y_at_x_right_2 compare_y_at_x_right_2_object () const 00942 { 00943 return 00944 (Compare_y_at_x_right_2(m_base_traits->compare_y_at_x_right_2_object())); 00945 } 00946 00947 // left-right 00948 00952 class Parameter_space_in_x_2 { 00953 protected: 00955 const Traits_2 * m_base; 00956 00962 Parameter_space_in_x_2 (const Traits_2 * tr) : m_base (tr) {} 00963 00965 friend class Arr_overlay_traits_2<Traits_2, 00966 Arrangement_red_2, 00967 Arrangement_blue_2>; 00968 00969 public: 00970 Arr_parameter_space operator() (const X_monotone_curve_2 & xcv, 00971 Arr_curve_end ce) const 00972 { 00973 return m_base->parameter_space_in_x_2_object() (xcv.base(), ce); 00974 } 00975 00976 Arr_parameter_space operator() (const Point_2 & p) const 00977 { 00978 return m_base->parameter_space_in_x_2_object() (p.base()); 00979 } 00980 00981 Arr_parameter_space operator() (const X_monotone_curve_2 & xcv) const 00982 { 00983 return m_base->parameter_space_in_x_2_object() (xcv.base()); 00984 } 00985 00986 }; 00987 00991 class Compare_y_near_boundary_2 { 00992 protected: 00994 const Traits_2 * m_base; 00995 01003 Compare_y_near_boundary_2(const Traits_2 * base) : m_base(base) {} 01004 01006 friend class Arr_overlay_traits_2<Traits_2, 01007 Arrangement_red_2, 01008 Arrangement_blue_2>; 01009 01010 public: 01011 Comparison_result operator() (const X_monotone_curve_2 & xcv1, 01012 const X_monotone_curve_2 & xcv2, 01013 Arr_curve_end ce) const 01014 { 01015 // If the traits class does not support open curves, we just 01016 // return EQUAL, as this comparison will not be invoked anyway. 01017 return m_base->compare_y_near_boundary_2_object()(xcv1.base(), 01018 xcv2.base(), ce); 01019 } 01020 }; 01021 01023 Compare_y_near_boundary_2 compare_y_near_boundary_2_object () const 01024 { 01025 return Compare_y_near_boundary_2(m_base_traits); 01026 } 01027 01028 // TODO Compare_y_on_boundary_2 01029 // TODO Is_on_x_identification_2 01030 01031 // bottom-top 01032 01034 Parameter_space_in_x_2 parameter_space_in_x_2_object () const 01035 { 01036 return Parameter_space_in_x_2 (m_base_traits); 01037 } 01038 01042 class Parameter_space_in_y_2 { 01043 protected: 01045 const Traits_2 * m_base; 01046 01052 Parameter_space_in_y_2 (const Traits_2 *tr) : m_base (tr) {} 01053 01055 friend class Arr_overlay_traits_2<Traits_2, 01056 Arrangement_red_2, 01057 Arrangement_blue_2>; 01058 01059 public: 01060 Arr_parameter_space operator() (const X_monotone_curve_2 & xcv, 01061 Arr_curve_end ce) const 01062 { 01063 return m_base->parameter_space_in_y_2_object()(xcv.base(), ce); 01064 } 01065 01066 Arr_parameter_space operator()(const Point_2 & p) const 01067 { 01068 return m_base->parameter_space_in_y_2_object()(p.base()); 01069 } 01070 01071 Arr_parameter_space operator()(const X_monotone_curve_2 & xcv) const 01072 { 01073 return m_base->parameter_space_in_y_2_object()(xcv.base()); 01074 } 01075 01076 }; 01077 01079 Parameter_space_in_y_2 parameter_space_in_y_2_object () const 01080 { 01081 return (Parameter_space_in_y_2 (m_base_traits)); 01082 } 01083 01087 class Compare_x_near_boundary_2 { 01088 protected: 01090 const Traits_2 * m_base; 01091 01099 Compare_x_near_boundary_2(const Traits_2 * base) : m_base(base) {} 01100 01102 friend class Arr_overlay_traits_2<Traits_2, 01103 Arrangement_red_2, 01104 Arrangement_blue_2>; 01105 01106 public: 01107 Comparison_result operator()(const Point_2 & p, 01108 const X_monotone_curve_2 & xcv, 01109 Arr_curve_end ce) const 01110 { 01111 return m_base->compare_x_near_boundary_2_object()(p.base(), 01112 xcv.base(), ce); 01113 } 01114 01115 Comparison_result operator()(const X_monotone_curve_2 & xcv1, 01116 Arr_curve_end ce1, 01117 const X_monotone_curve_2 & xcv2, 01118 Arr_curve_end ce2) const 01119 { 01120 return m_base->compare_x_near_boundary_2_object()(xcv1.base(), ce1, 01121 xcv2.base(), ce2); 01122 } 01123 01124 }; 01125 01127 Compare_x_near_boundary_2 compare_x_near_boundary_2_object () const 01128 { 01129 return Compare_x_near_boundary_2(m_base_traits); 01130 } 01131 01132 // TODO Compare_x_on_boundary_2 01133 // TODO Is_on_y_identification_2 01134 01135 }; 01136 01137 CGAL_END_NAMESPACE 01138 01139 #endif