BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Boolean_set_operations_2/Gps_simplifier_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_simplifier_traits.h $
00015 // $Id: Gps_simplifier_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_SIMPLIFIER_TRAITS_H
00021 #define CGAL_GPS_SIMPLIFIER_TRAITS_H
00022 
00023 #include <CGAL/Boolean_set_operations_2/Gps_traits_decorator.h>
00024 
00025 CGAL_BEGIN_NAMESPACE
00026 
00027 class Gps_simplifier_curve_data
00028 {
00029 protected:
00030   unsigned int m_bc;
00031   unsigned int m_twin_bc;
00032   unsigned int m_index;
00033 
00034 public:
00035   Gps_simplifier_curve_data()
00036   {}
00037 
00038   Gps_simplifier_curve_data(unsigned int bc,
00039                             unsigned int twin_bc,
00040                             unsigned int index):
00041     m_bc(bc),
00042     m_twin_bc(twin_bc),
00043     m_index(index)
00044   {}
00045 
00046   unsigned int bc() const
00047   {
00048     return m_bc;
00049   }
00050 
00051   unsigned int twin_bc() const
00052   {
00053     return m_twin_bc;
00054   }
00055 
00056   unsigned int index() const
00057   {
00058     return m_index;
00059   }
00060 
00061   unsigned int& index() 
00062   {
00063     return m_index;
00064   }
00065 
00066   unsigned int& twin_bc() 
00067   {
00068     return m_twin_bc;
00069   }
00070 
00071   void set_bc(unsigned int bc)
00072   {
00073     m_bc = bc;
00074   }
00075 
00076   void set_twin_bc(unsigned int twin_bc)
00077   {
00078     m_twin_bc = twin_bc;
00079   }
00080 
00081   void set_index(unsigned int index)
00082   {
00083     m_index = index;
00084   }
00085 };
00086 
00087 struct Gps_simplifier_point_data
00088 {
00089 protected:
00090   unsigned int m_index;
00091 
00092 public:
00093   Gps_simplifier_point_data()
00094   {}
00095 
00096   Gps_simplifier_point_data(unsigned int index) : m_index(index)
00097   {}
00098 
00099   unsigned int index() const
00100   {
00101     return m_index;
00102   }
00103   
00104   void set_index(unsigned int index)
00105   {
00106     m_index = index;
00107   }
00108 };
00109 
00110 template <class Traits_>
00111 class Gps_simplifier_traits :
00112   public Gps_traits_decorator<Traits_,
00113                               Gps_simplifier_curve_data,
00114                               Gps_simplifier_point_data>
00115 {
00116 public:
00117   typedef Traits_    Traits;
00118   typedef Gps_traits_decorator<Traits_,
00119                                Gps_simplifier_curve_data,
00120                                Gps_simplifier_point_data>    Base;
00121   typedef Gps_simplifier_traits<Traits>                      Self;
00122   typedef typename Traits::X_monotone_curve_2     Base_X_monotone_curve_2;
00123   typedef typename Traits::Point_2                Base_Point_2;
00124   typedef typename Traits::Construct_min_vertex_2 Base_Construct_min_vertex_2;
00125   typedef typename Traits::Construct_max_vertex_2 Base_Construct_max_vertex_2;
00126   typedef typename Traits::Compare_endpoints_xy_2 Base_Compare_endpoints_xy_2;
00127   typedef typename Traits::Compare_xy_2           Base_Compare_xy_2;
00128   typedef typename Traits::Compare_y_at_x_right_2 Base_Compare_y_at_x_right_2;
00129   typedef typename Traits::Compare_y_at_x_2       Base_Compare_y_at_x_2;
00130   typedef typename Traits::Intersect_2            Base_Intersect_2;
00131   typedef typename Traits::Split_2                Base_Split_2;
00132 
00133 protected:
00134   unsigned int m_pgn_size;
00135 
00136   
00137 public:
00138 
00139   typedef typename Base::X_monotone_curve_2       X_monotone_curve_2;
00140   typedef typename Base::Point_2                  Point_2;
00141 
00142   typedef typename Base::Curve_data               Curve_data;
00143   typedef typename Base::Point_data               Point_data;
00144 
00145   Gps_simplifier_traits()
00146   {}
00147 
00148   Gps_simplifier_traits(const Traits & tr) : Base(tr)
00149   {}
00150 
00151   unsigned int polygon_size() const
00152   {
00153     return m_pgn_size;
00154   }
00155 
00156   void set_polygon_size(unsigned int pgn_size)
00157   {
00158     m_pgn_size = pgn_size;
00159   }
00160 
00161   bool is_valid_index(unsigned int index) const
00162   {
00163     return (index < m_pgn_size);
00164   }
00165 
00166   unsigned int invalid_index() const
00167   {
00168     return (m_pgn_size);
00169   }
00170 
00171 
00172   class Intersect_2
00173   {
00174   private:
00175 
00176     Base_Intersect_2             m_base;
00177     Base_Compare_endpoints_xy_2  m_base_cmp_endpoints;
00178     Base_Compare_xy_2            m_base_cmp_xy;
00179     Base_Construct_min_vertex_2  m_ctr_min_v;
00180     const Self * m_self_tr;
00181 
00182   public:
00183    
00185     Intersect_2 (const Base_Intersect_2& base,
00186                  const Base_Compare_endpoints_xy_2& base_cmp_endpoints,
00187                  const Base_Compare_xy_2& base_cmp_xy,
00188                  const Base_Construct_min_vertex_2& ,
00189                  const Self*  tr) : 
00190       m_base(base),
00191       m_base_cmp_endpoints(base_cmp_endpoints),
00192       m_base_cmp_xy(base_cmp_xy),
00193       m_self_tr(tr)
00194     {}
00195 
00196     template<class OutputIterator>
00197     OutputIterator operator() (const X_monotone_curve_2& cv1,
00198                                const X_monotone_curve_2& cv2,
00199                                OutputIterator oi) const
00200     {
00202       //if(m_self_tr->is_valid_index(cv1.data().index()) && 
00203       //   m_self_tr->is_valid_index(cv2.data().index()))
00204       //{
00205       //  unsigned int index_diff = 
00206       //    (cv1.data().index() > cv2.data().index()) ? 
00207       //    (cv1.data().index() - cv2.data().index()):
00208       //    (cv2.data().index() - cv1.data().index());
00209 
00210       //  if(index_diff == 1 ||index_diff == m_self_tr->polygon_size() -1)
00211       //  {
00212       //    return (oi);
00213       //  }
00214       //}
00215       const std::pair<Base_Point_2, unsigned int>   *base_pt;
00216       const Base_X_monotone_curve_2                 *overlap_cv;
00217       OutputIterator oi_end;
00218       if(m_base_cmp_xy(m_ctr_min_v(cv1.base()),
00219                        m_ctr_min_v(cv2.base())) == LARGER)
00220         oi_end = m_base(cv1.base(), cv2.base(), oi);
00221       else
00222         oi_end = m_base(cv2.base(), cv1.base(), oi);
00223 
00224       // convert objects that are associated with Base_X_monotone_curve_2 to
00225       // the extenede X_monotone_curve_2 
00226       for(; oi != oi_end; ++oi)
00227       {
00228         base_pt = object_cast<std::pair<Base_Point_2, unsigned int> >(&(*oi));
00229 
00230         if (base_pt != NULL)
00231         {
00232           Point_data pt_data(m_self_tr->invalid_index());
00233           Point_2 point_plus (base_pt->first, pt_data); // the extended point
00234           *oi = CGAL::make_object(std::make_pair(point_plus, 
00235                                                  base_pt->second));
00236         }
00237         else
00238         {
00239           overlap_cv = object_cast<Base_X_monotone_curve_2> (&(*oi));
00240 
00241           if (overlap_cv != NULL)
00242           {
00243             unsigned int ov_bc;
00244             unsigned int ov_twin_bc;
00245             if(m_base_cmp_endpoints(cv1) == m_base_cmp_endpoints(cv2))
00246             {
00247               // cv1 and cv2 have the same directions
00248               ov_bc = cv1.data().bc() + cv2.data().bc();
00249               ov_twin_bc = cv1.data().twin_bc() + cv2.data().twin_bc();
00250             }
00251             else
00252             {
00253               // cv1 and cv2 have opposite directions
00254               ov_bc = cv1.data().bc() + cv2.data().twin_bc();
00255               ov_twin_bc = cv1.data().twin_bc() + cv2.data().bc();
00256             }
00257 
00258             if(m_base_cmp_endpoints(*overlap_cv) != m_base_cmp_endpoints(cv1))
00259             {
00260               // overlap_cv, cv1 have opposite directions
00261               std::swap(ov_bc, ov_twin_bc);
00262             }
00263 
00264             Curve_data cv_data(ov_bc, ov_twin_bc, m_self_tr->invalid_index());
00265             *oi = CGAL::make_object (X_monotone_curve_2 (*overlap_cv, cv_data));
00266           }
00267         }
00268       }
00269       //return past-end iterator
00270       return oi_end;
00271     }
00272   };
00273 
00275   Intersect_2 intersect_2_object () const
00276   {
00277     return Intersect_2(this->m_base_tr->intersect_2_object(),
00278                        this->m_base_tr->compare_endpoints_xy_2_object(),
00279                        this->m_base_tr->compare_xy_2_object(),
00280                        this->m_base_tr->construct_min_vertex_2_object(),
00281                        this);
00282   }
00283 
00284   class Split_2
00285   {
00286   private:
00287     Base_Split_2      m_base_split;
00288     const Self * m_self_tr;
00289 
00290   public:
00291 
00293     Split_2 (const Base_Split_2& base, const Self* tr) :
00294       m_base_split(base),
00295       m_self_tr(tr)
00296     {}
00297 
00298     void operator() (const X_monotone_curve_2& cv, const Point_2 & p,
00299                      X_monotone_curve_2& c1, X_monotone_curve_2& c2) const
00300     {
00301       m_base_split(cv.base(),
00302                    p.base(),
00303                    c1.base(),
00304                    c2.base());
00305       const Curve_data& cv_data = cv.data();
00306       c1.set_data(Curve_data(cv_data.bc(),
00307                              cv_data.twin_bc(),
00308                              m_self_tr->invalid_index()));
00309       
00310       c2.set_data(Curve_data(cv_data.bc(),
00311                              cv_data.twin_bc(),
00312                              m_self_tr->invalid_index()));
00313     }
00314   };
00315 
00317   Split_2 split_2_object () const
00318   {
00319     return Split_2(this->m_base_tr->split_2_object(), this);
00320   }
00321 
00322   class Construct_min_vertex_2
00323   {
00324   private:
00325     Base_Construct_min_vertex_2 m_base;
00326     Base_Compare_endpoints_xy_2 m_base_cmp_endpoints;
00327     const Self * m_self_tr;
00328 
00329   public:
00330 
00331     Construct_min_vertex_2(const Base_Construct_min_vertex_2& base,
00332                           const Base_Compare_endpoints_xy_2& base_cmp_endpoints,
00333                           const Self * tr):
00334       m_base(base),
00335       m_base_cmp_endpoints(base_cmp_endpoints),
00336       m_self_tr(tr)
00337     {}
00338 
00344     Point_2 operator() (const X_monotone_curve_2 & cv) const
00345     {
00346       if(!m_self_tr->is_valid_index(cv.data().index()))
00347       {
00348         return Point_2 (m_base(cv.base()), m_self_tr->invalid_index());
00349       }
00350       
00351       Comparison_result res = m_base_cmp_endpoints(cv);
00352       Point_data pt_data;
00353       if(res == SMALLER)
00354       {
00355         // min vertex is the source
00356         pt_data.set_index(cv.data().index());
00357       }
00358       else
00359       {
00360         // min vertex is the target
00361         pt_data.set_index((cv.data().index() + 1) % m_self_tr->polygon_size());
00362       }
00363       return Point_2 (m_base(cv.base()), pt_data);
00364     }
00365   };
00366 
00368   Construct_min_vertex_2 construct_min_vertex_2_object () const
00369   {
00370     return Construct_min_vertex_2
00371       (this->m_base_tr->construct_min_vertex_2_object(),
00372        this->m_base_tr->compare_endpoints_xy_2_object(),
00373        this);
00374   }
00375 
00376 
00377   class Construct_max_vertex_2
00378   {
00379   private:
00380     Base_Construct_max_vertex_2      m_base;
00381     Base_Compare_endpoints_xy_2      m_base_cmp_endpoints;
00382     const Self * m_self_tr;
00383 
00384   public:
00385 
00386     Construct_max_vertex_2(const Base_Construct_max_vertex_2& base,
00387                           const Base_Compare_endpoints_xy_2& base_cmp_endpoints,
00388                           const Self * tr):
00389       m_base(base),
00390       m_base_cmp_endpoints(base_cmp_endpoints),
00391       m_self_tr(tr)
00392     {}
00393 
00399     Point_2 operator() (const X_monotone_curve_2 & cv) const
00400     {
00401       if(!m_self_tr->is_valid_index(cv.data().index()))
00402       {
00403         return Point_2 (m_base(cv.base()), m_self_tr->invalid_index());
00404       }
00405       Comparison_result res = m_base_cmp_endpoints(cv);
00406       Point_data pt_data;
00407       if(res == SMALLER)
00408       {
00409         // min vertex is the target
00410         pt_data.set_index((cv.data().index() + 1) % m_self_tr->polygon_size());
00411       }
00412       else
00413       {
00414         // min vertex is the source
00415         pt_data.set_index(cv.data().index());
00416       }
00417       return Point_2 (m_base(cv.base()), pt_data);
00418     }
00419   };
00420 
00422   Construct_max_vertex_2 construct_max_vertex_2_object () const
00423   {
00424     return Construct_max_vertex_2
00425       (this->m_base_tr->construct_max_vertex_2_object(),
00426        this->m_base_tr->compare_endpoints_xy_2_object(),
00427        this);
00428   }
00429 
00430   class Compare_xy_2
00431   {
00432   private:
00433     Base_Compare_xy_2       m_base;
00434     const Self * m_self_tr;
00435 
00436   public:
00437     Compare_xy_2(const Base_Compare_xy_2& base,
00438                  const Self * tr):
00439       m_base(base),
00440       m_self_tr(tr)
00441     {}
00442 
00443 
00449     Comparison_result operator() (const Point_2& p1, const Point_2& p2) const
00450     {
00451       //if one of the indexes is invalid, compare p1 and p2
00452       if(! m_self_tr->is_valid_index(p1.data().index()) ||
00453         ! m_self_tr->is_valid_index(p2.data().index()))
00454         return (m_base(p1.base(), p2.base()));
00455 
00456       // if the two point has the same index, return EQUAL
00457       if(p1.data().index() == p2.data().index())
00458       {
00459         return EQUAL;
00460       }
00461 
00462       return (m_base(p1.base(), p2.base()));
00463     }
00464   };
00465 
00466 
00468   Compare_xy_2 compare_xy_2_object () const
00469   {
00470     return Compare_xy_2(this->m_base_tr->compare_xy_2_object(), this);
00471   }
00472 };
00473 
00474 CGAL_END_NAMESPACE
00475 
00476 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines