BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Sweep_line_2/Arr_overlay_traits_2.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/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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines