BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Boolean_set_operations_2/Gps_agg_meta_traits.h
Go to the documentation of this file.
00001 // Copyright (c) 1997  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/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_agg_meta_traits.h $
00015 // $Id: Gps_agg_meta_traits.h 50373 2009-07-05 14:44:48Z efif $
00016 // 
00017 //
00018 // Author(s)     : Baruch Zukerman <baruchzu@post.tau.ac.il>
00019 
00020 #ifndef CGAL_GPS_AGG_META_TRAITS_H
00021 #define CGAL_GPS_AGG_META_TRAITS_H
00022 
00023 #include <vector>
00024 #include <boost/mpl/assert.hpp>
00025 #include <CGAL/Boolean_set_operations_2/Gps_traits_decorator.h>
00026 #include <CGAL/Boolean_set_operations_2/Curve_with_halfedge.h>
00027 #include <CGAL/Boolean_set_operations_2/Point_with_vertex.h>
00028 
00029 CGAL_BEGIN_NAMESPACE
00030 
00031 template <class Arrangement_>
00032 class Gps_agg_curve_data : public Curve_with_halfedge<Arrangement_>
00033 {
00034 protected:
00035   typedef Arrangement_                             Arrangement;
00036   typedef typename Arrangement::Halfedge_handle    Halfedge_handle;
00037   typedef Curve_with_halfedge<Arrangement_>        Base;
00038 
00039   const Arrangement*  m_arr; // pointer to the arrangement containing the edge.
00040   unsigned int        m_bc; // the boudary counter of the halfedge with the same
00041                           //direction as the curve
00042 
00043   unsigned int      m_twin_bc;  // the boudary counter of the halfedge with the same
00044                                  //direction as the curve
00045 
00046 public:
00047 
00048   Gps_agg_curve_data() :
00049     Base(),
00050     m_arr(NULL),
00051     m_bc(0),
00052     m_twin_bc(0)
00053   {}
00054 
00055   Gps_agg_curve_data(const Arrangement* arr,
00056                      Halfedge_handle he,
00057                      unsigned int bc,
00058                      unsigned int twin_bc):
00059     Base(he),
00060     m_arr(arr),
00061     m_bc(bc),
00062     m_twin_bc(twin_bc)
00063   {}
00064 
00065   unsigned int bc() const
00066   {
00067     return m_bc;
00068   }
00069 
00070   unsigned int twin_bc() const
00071   {
00072     return m_twin_bc;
00073   }
00074 
00075   unsigned int& bc() 
00076   {
00077     return m_bc;
00078   }
00079 
00080   unsigned int& twin_bc() 
00081   {
00082     return m_twin_bc;
00083   }
00084 
00085   void set_bc(unsigned int bc)
00086   {
00087     m_bc = bc;
00088   }
00089 
00090   void set_twin_bc(unsigned int twin_bc)
00091   {
00092     m_twin_bc = twin_bc;
00093   }
00094 
00095   const Arrangement* arr() const
00096   {
00097     return m_arr;
00098   }
00099 
00100 };
00101 
00102 
00103 template <class Arrangement_>
00104 class Gps_agg_meta_traits :
00105   public Gps_traits_decorator<typename Arrangement_::Traits_adaptor_2,
00106                               Gps_agg_curve_data<Arrangement_>,
00107                               Point_with_vertex<Arrangement_> >
00108 {
00109   typedef Arrangement_                            Arrangement;
00110   typedef typename Arrangement::Traits_adaptor_2  Traits;
00111 
00112   typedef typename Traits::X_monotone_curve_2     Base_X_monotone_curve_2;
00113   typedef typename Traits::Point_2                Base_Point_2;
00114   typedef typename Traits::Construct_min_vertex_2 Base_Construct_min_vertex_2;
00115   typedef typename Traits::Construct_max_vertex_2 Base_Construct_max_vertex_2;
00116   typedef typename Traits::Compare_endpoints_xy_2 Base_Compare_endpoints_xy_2;
00117   typedef typename Traits::Compare_xy_2           Base_Compare_xy_2;
00118   typedef typename Traits::Compare_y_at_x_right_2 Base_Compare_y_at_x_right_2;
00119   typedef typename Traits::Compare_y_at_x_2       Base_Compare_y_at_x_2;
00120   typedef typename Traits::Intersect_2            Base_Intersect_2;
00121   typedef typename Traits::Split_2                Base_Split_2;
00122 
00123   typedef typename Traits::Parameter_space_in_x_2 Base_Parameter_space_in_x_2;
00124   typedef typename Traits::Compare_y_near_boundary_2 
00125                                                  Base_Compare_y_near_boundary_2;
00126 
00127   typedef typename Traits::Parameter_space_in_y_2 Base_Parameter_space_in_y_2;
00128   typedef typename Traits::Compare_x_near_boundary_2 
00129                                                  Base_Compare_x_near_boundary_2;
00130 
00131 
00132   typedef Gps_agg_meta_traits<Traits>             Self;
00133   typedef Gps_traits_decorator<Traits,
00134                                Gps_agg_curve_data<Arrangement_>,
00135                                Point_with_vertex<Arrangement_> > 
00136                                                   Base;
00137 
00138   public:
00139   typedef typename Base::X_monotone_curve_2       X_monotone_curve_2;
00140   typedef typename Base::Point_2                  Point_2;
00141   typedef typename Traits::Has_left_category      Has_left_category;
00142   typedef typename Traits::Has_merge_category     Has_merge_category;
00143 
00144   typedef typename Arrangement::Arr_left_side_tag   Arr_left_side_tag;
00145   typedef typename Arrangement::Arr_bottom_side_tag Arr_bottom_side_tag;
00146   typedef typename Arrangement::Arr_top_side_tag    Arr_top_side_tag;
00147   typedef typename Arrangement::Arr_right_side_tag  Arr_right_side_tag;
00148 
00149   // a side is either oblivious or open (unbounded)
00150   BOOST_MPL_ASSERT(
00151       (boost::mpl::or_< 
00152        boost::is_same< Arr_left_side_tag, Arr_oblivious_side_tag >,
00153        boost::is_same< Arr_left_side_tag, Arr_open_side_tag > >
00154       )
00155   );
00156   BOOST_MPL_ASSERT(
00157       (boost::mpl::or_< 
00158        boost::is_same< Arr_bottom_side_tag, Arr_oblivious_side_tag >,
00159        boost::is_same< Arr_bottom_side_tag, Arr_open_side_tag > >
00160       )
00161   );
00162   BOOST_MPL_ASSERT(
00163       (boost::mpl::or_< 
00164        boost::is_same< Arr_top_side_tag, Arr_oblivious_side_tag >,
00165        boost::is_same< Arr_top_side_tag, Arr_open_side_tag > >
00166       )
00167   );
00168   BOOST_MPL_ASSERT(
00169       (boost::mpl::or_< 
00170        boost::is_same< Arr_right_side_tag, Arr_oblivious_side_tag >,
00171        boost::is_same< Arr_right_side_tag, Arr_open_side_tag > >
00172       )
00173   );
00174 
00175   typedef typename Base::Curve_data               Curve_data;
00176   typedef typename Base::Point_data               Point_data;
00177 
00178   typedef typename Arrangement::Halfedge_handle   Halfedge_handle;
00179   typedef typename Arrangement::Vertex_handle     Vertex_handle;
00180 
00181 
00182   Gps_agg_meta_traits()
00183   {}
00184 
00185   Gps_agg_meta_traits(const Traits & base_tr) : Base(base_tr)
00186   {}
00187 
00188   class Intersect_2
00189   {
00190   private:
00191     Base_Intersect_2             m_base;
00192     Base_Compare_endpoints_xy_2  m_base_cmp_endpoints;
00193     Base_Compare_xy_2            m_base_cmp_xy;
00194     Base_Construct_min_vertex_2  m_base_ctr_min_v;
00195 
00196   public:
00198     Intersect_2 (const Base_Intersect_2& base,
00199                  const Base_Compare_endpoints_xy_2& base_cmp_endpoints,
00200                  const Base_Compare_xy_2& base_cmp_xy,
00201                  const Base_Construct_min_vertex_2& base_ctr_min_v) : 
00202       m_base(base),
00203       m_base_cmp_endpoints(base_cmp_endpoints),
00204       m_base_cmp_xy(base_cmp_xy),
00205       m_base_ctr_min_v(base_ctr_min_v)
00206     {}
00207 
00208     template<class OutputIterator>
00209     OutputIterator operator() (const X_monotone_curve_2& cv1,
00210                                const X_monotone_curve_2& cv2,
00211                                OutputIterator oi) const
00212     {
00213       if (cv1.data().arr() == cv2.data().arr())
00214       {
00215         return (oi); // the curves are disjoint-interior because they
00216                      // are already at the same arrangement.
00217       }
00218       
00219       const std::pair<Base_Point_2, unsigned int>   *base_pt;
00220       const Base_X_monotone_curve_2                 *overlap_cv;
00221       OutputIterator oi_end;
00222       if(m_base_cmp_xy(m_base_ctr_min_v(cv1.base()),
00223                        m_base_ctr_min_v(cv2.base())) == LARGER)
00224         oi_end = m_base(cv1.base(), cv2.base(), oi);
00225       else
00226         oi_end = m_base(cv2.base(), cv1.base(), oi);
00227 
00228       // convert objects that are associated with Base_X_monotone_curve_2 to
00229       // the extenede X_monotone_curve_2 
00230       for(; oi != oi_end; ++oi)
00231       {
00232         base_pt = object_cast<std::pair<Base_Point_2, unsigned int> >(&(*oi));
00233 
00234         if (base_pt != NULL)
00235         {
00236           Point_2 point_plus (base_pt->first); // the extended point
00237           *oi = CGAL::make_object(std::make_pair(point_plus, 
00238                                                  base_pt->second));
00239         }
00240         else
00241         {
00242           overlap_cv = object_cast<Base_X_monotone_curve_2> (&(*oi));
00243 
00244           if (overlap_cv != NULL)
00245           {
00246             unsigned int ov_bc;
00247             unsigned int ov_twin_bc;
00248             if (m_base_cmp_endpoints(cv1) == m_base_cmp_endpoints(cv2))
00249             {
00250               // cv1 and cv2 have the same directions
00251               ov_bc = cv1.data().bc() + cv2.data().bc();
00252               ov_twin_bc = cv1.data().twin_bc() + cv2.data().twin_bc();
00253             }
00254             else
00255             {
00256               // cv1 and cv2 have opposite directions
00257               ov_bc = cv1.data().bc() + cv2.data().twin_bc();
00258               ov_twin_bc = cv1.data().twin_bc() + cv2.data().bc();
00259             }
00260 
00261             if(m_base_cmp_endpoints(*overlap_cv) != m_base_cmp_endpoints(cv1))
00262             {
00263               // overlap_cv, cv1 have opposite directions
00264               std::swap(ov_bc, ov_twin_bc);
00265             }
00266 
00267             Curve_data cv_data(cv1.data().arr(),
00268                                Halfedge_handle(),
00269                                ov_bc, ov_twin_bc);
00270               *oi = CGAL::make_object (X_monotone_curve_2(*overlap_cv, cv_data));
00271           }
00272         }
00273       }
00274       //return past-end iterator
00275       return oi_end;
00276     }
00277   };
00278 
00280   Intersect_2 intersect_2_object () const
00281   {
00282     return Intersect_2(this->m_base_tr->intersect_2_object(),
00283                        this->m_base_tr->compare_endpoints_xy_2_object(),
00284                        this->m_base_tr->compare_xy_2_object(),
00285                        this->m_base_tr->construct_min_vertex_2_object());
00286   }
00287 
00288 
00289   class Split_2
00290   {
00291   private:
00292     Base_Split_2      m_base_split;
00293 
00294   public:
00295 
00297     Split_2 (const Base_Split_2& base) : m_base_split (base)
00298     {}
00299 
00300     void operator() (const X_monotone_curve_2& cv, const Point_2 & p,
00301                      X_monotone_curve_2& c1, X_monotone_curve_2& c2) const
00302     {
00303       m_base_split(cv.base(),
00304                    p.base(),
00305                    c1.base(),
00306                    c2.base());
00307       const Curve_data& cv_data = cv.data();
00308       c1.set_data(Curve_data(cv_data.arr(),
00309                              Halfedge_handle(),
00310                              cv_data.bc(),
00311                              cv_data.twin_bc()));
00312       
00313       c2.set_data(Curve_data(cv_data.arr(),
00314                              Halfedge_handle(),
00315                              cv_data.bc(),
00316                              cv_data.twin_bc()));
00317     }
00318   };
00319 
00321   Split_2 split_2_object () const
00322   {
00323     return Split_2(this->m_base_tr->split_2_object());
00324   }
00325 
00326 
00327   class Construct_min_vertex_2
00328   {
00329   private:
00330     Base_Construct_min_vertex_2 m_base;
00331 
00332   public:
00333 
00334     Construct_min_vertex_2(const Base_Construct_min_vertex_2& base) :
00335         m_base(base)
00336     {}
00337   
00343     Point_2 operator() (const X_monotone_curve_2 & cv) const
00344     {
00345       if(cv.data().halfedge() == Halfedge_handle())
00346         return (Point_2 (m_base(cv.base())));
00347 
00348       CGAL_assertion
00349         ((Arr_halfedge_direction)cv.data().halfedge()->direction() ==
00350          ARR_LEFT_TO_RIGHT);
00351       return Point_2 (m_base(cv.base()), cv.data().halfedge()->source());
00352     }
00353   };
00354 
00356   Construct_min_vertex_2 construct_min_vertex_2_object () const
00357   {
00358     return Construct_min_vertex_2(this->m_base_tr->
00359                                   construct_min_vertex_2_object());
00360   }
00361 
00362 
00363   class Construct_max_vertex_2
00364   {
00365   private:
00366     Base_Construct_max_vertex_2 m_base;
00367 
00368   public:
00369 
00370     Construct_max_vertex_2(const Base_Construct_max_vertex_2& base):
00371         m_base(base)
00372     {}
00373   
00379     Point_2 operator() (const X_monotone_curve_2 & cv) const
00380     {
00381       if(cv.data().halfedge() == Halfedge_handle())
00382         return (Point_2 (m_base(cv.base())));
00383 
00384       CGAL_assertion((Arr_halfedge_direction)cv.data().halfedge()->direction() ==
00385                      ARR_LEFT_TO_RIGHT);
00386       return Point_2 (m_base(cv.base()), cv.data().halfedge()->target());
00387     }
00388   };
00389 
00391   Construct_max_vertex_2 construct_max_vertex_2_object () const
00392   {
00393     return Construct_max_vertex_2(this->m_base_tr->
00394                                   construct_max_vertex_2_object());
00395   }
00396 
00397 
00398   class Compare_xy_2
00399   {
00400   private:
00401     Base_Compare_xy_2 m_base;
00402 
00403   public:
00404 
00405     Compare_xy_2(const Base_Compare_xy_2& base):
00406         m_base(base)
00407     {}
00408 
00409 
00415     Comparison_result operator() (const Point_2& p1, const Point_2& p2) const
00416     {
00417       const Point_data& inf1 = p1.data();
00418       const Point_data& inf2 = p2.data();
00419 
00420       if(inf1.vertex() == Vertex_handle() || inf2.vertex() == Vertex_handle())
00421       {
00422         return(m_base(p1.base(), p2.base()));
00423       }
00424 
00425       if(inf1.vertex() == inf2.vertex())
00426         return (EQUAL);
00427 
00428       return(m_base(p1.base(), p2.base()));
00429     }
00430   };
00431 
00432 
00434   Compare_xy_2 compare_xy_2_object () const
00435   {
00436     return Compare_xy_2(this->m_base_tr->compare_xy_2_object());
00437   }
00438 
00439 
00440 
00441   // left-right
00442 
00443   
00444   class Parameter_space_in_x_2
00445   {
00446   private:
00447     Base_Parameter_space_in_x_2 m_base;
00448     
00449   public:
00450     
00451     Parameter_space_in_x_2(const Base_Parameter_space_in_x_2& base):
00452       m_base(base)
00453     {}
00454     
00457     Arr_parameter_space operator() (const X_monotone_curve_2 & cv, 
00458                                     const Arr_curve_end& end) const
00459     {
00460       return m_base(cv.base(), end);
00461     }
00462     
00465     Arr_parameter_space operator() (const X_monotone_curve_2 & cv) const
00466     {
00467       return m_base(cv.base());
00468     }
00469 
00472     Arr_parameter_space operator() (const Point_2 & pt) const
00473     {
00474       return m_base(pt.base());
00475     }
00476   };
00477   
00479   Parameter_space_in_x_2 parameter_space_in_x_2_object () const
00480   {
00481     return Parameter_space_in_x_2(
00482         this->m_base_tr->parameter_space_in_x_2_object()
00483     );
00484   }
00485 
00486   class Compare_y_near_boundary_2
00487   {
00488   private:
00489     Base_Compare_y_near_boundary_2 m_base;
00490     
00491   public:
00492     
00493     Compare_y_near_boundary_2(const Base_Compare_y_near_boundary_2& base):
00494       m_base(base)
00495     {}
00496     
00500     Comparison_result operator() (const X_monotone_curve_2 & xcv1,
00501                                   const X_monotone_curve_2 & xcv2, 
00502                                   Arr_curve_end ce) const
00503     {
00504       return m_base(xcv1, xcv2, ce);
00505     }
00506   };
00507   
00509   Compare_y_near_boundary_2 compare_y_near_boundary_2_object () const
00510   {
00511     return Compare_y_near_boundary_2(
00512         this->m_base_tr->compare_y_near_boundary_2_object()
00513     );
00514   }
00515 
00516   // TODO Compare_y_on_boundary_2
00517   // TODO Is_on_x_identification_2
00518 
00519   // bottom-top
00520 
00521 
00522   class Parameter_space_in_y_2
00523   {
00524   private:
00525     Base_Parameter_space_in_y_2 m_base;
00526     
00527   public:
00528     
00529     Parameter_space_in_y_2(const Base_Parameter_space_in_y_2& base):
00530       m_base(base)
00531     {}
00532     
00535     Arr_parameter_space operator() (const X_monotone_curve_2 & cv, 
00536                                     const Arr_curve_end& end) const
00537     {
00538       return m_base(cv.base(), end);
00539     }
00540     
00543     Arr_parameter_space operator() (const X_monotone_curve_2 & cv) const
00544     {
00545       return m_base(cv.base());
00546     }
00547 
00550     Arr_parameter_space operator() (const Point_2 & pt) const
00551     {
00552       return m_base(pt.base());
00553     }
00554     
00555   };
00556   
00558   Parameter_space_in_y_2 parameter_space_in_y_2_object () const
00559   {
00560     return Parameter_space_in_y_2
00561       (this->m_base_tr->parameter_space_in_y_2_object());
00562   }
00563 
00564   class Compare_x_near_boundary_2
00565   {
00566   private:
00567     Base_Compare_x_near_boundary_2 m_base;
00568     
00569   public:
00570     
00571     Compare_x_near_boundary_2(const Base_Compare_x_near_boundary_2& base):
00572       m_base(base)
00573     {}
00574     
00578     Comparison_result operator() (const Point_2 & p,
00579                                   const X_monotone_curve_2 & xcv,
00580                                   Arr_curve_end ce) const
00581     {
00582       return m_base(p, xcv, ce);
00583     }
00584 
00587     Comparison_result operator() (const X_monotone_curve_2 & xcv1,
00588                                   Arr_curve_end ce1,
00589                                   const X_monotone_curve_2 & xcv2,
00590                                   Arr_curve_end ce2) const
00591     {
00592       return m_base(xcv1, ce1, xcv2, ce2); 
00593     }
00594   };
00595   
00597   Compare_x_near_boundary_2 compare_x_near_boundary_2_object () const
00598   {
00599     return Compare_x_near_boundary_2
00600       (this->m_base_tr->compare_x_near_boundary_2_object());
00601   }
00602 
00603   // TODO Compare_x_on_boundary_2
00604   // TODO Is_on_y_identification_2
00605 
00606 };
00607 
00608 CGAL_END_NAMESPACE
00609 
00610 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines