BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Straight_skeleton_2/Straight_skeleton_builder_traits_2_aux.h
Go to the documentation of this file.
00001 // Copyright (c) 2006 Fernando Luis Cacciola Carballal. All rights reserved.
00002 //
00003 // This file is part of CGAL (www.cgal.org); you may redistribute it under
00004 // the terms of the Q Public License version 1.0.
00005 // See the file LICENSE.QPL distributed with CGAL.
00006 //
00007 // Licensees holding a valid commercial license may use this file in
00008 // accordance with the commercial license agreement provided with the software.
00009 //
00010 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00011 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00012 //
00013 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Straight_skeleton_2/include/CGAL/Straight_skeleton_2/Straight_skeleton_builder_traits_2_aux.h $
00014 // $Id: Straight_skeleton_builder_traits_2_aux.h 44674 2008-07-31 13:31:26Z spion $
00015 //
00016 // Author(s)     : Fernando Cacciola <fernando_cacciola@ciudad.com.ar>
00017 //
00018 #ifndef CGAL_STRAIGHT_SKELETON_BUILDER_TRAITS_2_AUX_H
00019 #define CGAL_STRAIGHT_SKELETON_BUILDER_TRAITS_2_AUX_H 1
00020 
00021 #include <CGAL/tags.h>
00022 #include <CGAL/Handle.h>
00023 #include <CGAL/Uncertain.h>
00024 #include <CGAL/certified_numeric_predicates.h>
00025 #include <CGAL/Quotient.h>
00026 #include <CGAL/certified_quotient_predicates.h>
00027 #include <CGAL/Unfiltered_predicate_adaptor.h>
00028 #include <CGAL/Filtered_predicate.h>
00029 #include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
00030 
00031 #include <boost/tuple/tuple.hpp>
00032 #include <boost/intrusive_ptr.hpp>
00033 #include <boost/optional/optional.hpp>
00034 #include <boost/none.hpp>
00035 
00036 
00037 #ifdef CGAL_USE_CORE
00038 #  include <CGAL/CORE_BigFloat.h>  
00039 #endif
00040 
00041 CGAL_BEGIN_NAMESPACE
00042 
00043 namespace CGAL_SS_i {
00044 
00045 using boost::optional ;
00046 using boost::intrusive_ptr ;
00047 
00048 template<class T> 
00049 T const& validate ( boost::optional<T> const& o ) 
00050 { 
00051   if ( !o )
00052     throw std::overflow_error("Arithmetic overflow");
00053   return *o ;  
00054 }
00055   
00056 template<class NT>  
00057 NT const& validate( NT const& n )
00058 { 
00059   if ( !CGAL_NTS is_finite(n) )
00060     throw std::overflow_error("Arithmetic overflow");
00061   return n ;  
00062 }
00063 
00064 // boost::make_optional is provided in Boost >= 1.34, but not before, so we define our own versions here.
00065 template<class T> optional<T> cgal_make_optional( T const& v ) { return optional<T>(v) ; }
00066 template<class T> optional<T> cgal_make_optional( bool cond, T const& v ) { return cond ? optional<T>(v) : optional<T>() ; }
00067 
00068 template<class K>
00069 struct Is_filtering_kernel
00070 {
00071   typedef Tag_false type ;
00072 } ;
00073 
00074 template<>
00075 struct Is_filtering_kernel< Exact_predicates_inexact_constructions_kernel >
00076 {
00077   typedef Tag_true type ;
00078 } ;
00079 
00080 //
00081 // This is the same as Filtered_construction but uses optional<result> instead of exceptions.
00082 //
00083 template <class AC
00084          ,class EC
00085          ,class FC
00086          ,class C2E
00087          ,class C2F
00088          ,class E2C
00089          ,class F2C
00090          ,bool Protection = true
00091 >
00092 class Exceptionless_filtered_construction
00093 {
00094 private:
00095   EC Exact_construction;
00096   FC Filter_construction;
00097   C2E To_Exact;
00098   C2F To_Filtered;
00099   E2C From_Exact;
00100   F2C From_Filtered;
00101 
00102   typedef typename AC::result_type  AC_result_type;
00103   typedef typename FC::result_type  FC_result_type;
00104   typedef typename EC::result_type  EC_result_type;
00105 
00106 public:
00107   typedef AC_result_type           result_type;
00108 
00109 public:
00110 
00111   Exceptionless_filtered_construction() {}
00112 
00113   template <class A1>
00114   result_type
00115   operator()(const A1 &a1) const
00116   {
00117     try
00118     {
00119       Protect_FPU_rounding<Protection> P;
00120       FC_result_type fr = Filter_construction(To_Filtered(a1));
00121       if ( fr )
00122         return From_Filtered(fr);
00123     }
00124     catch (Uncertain_conversion_exception) {}
00125 
00126     Protect_FPU_rounding<!Protection> P(CGAL_FE_TONEAREST);
00127     EC_result_type er = Exact_construction(To_Exact(a1)) ;
00128     return From_Exact(er);
00129   }
00130   
00131   template <class A1, class A2>
00132   result_type
00133   operator()(const A1 &a1, const A2 &a2) const
00134   {
00135     try
00136     {
00137       Protect_FPU_rounding<Protection> P;
00138       FC_result_type fr = Filter_construction(To_Filtered(a1),To_Filtered(a2));
00139       if ( fr )
00140         return From_Filtered(fr);
00141     }
00142     catch (Uncertain_conversion_exception) {}
00143     
00144     Protect_FPU_rounding<!Protection> P(CGAL_FE_TONEAREST);
00145     EC_result_type er = Exact_construction(To_Exact(a1), To_Exact(a2)) ;
00146     return From_Exact(er);
00147   }
00148   
00149   template <class A1, class A2, class A3>
00150   result_type
00151   operator()(const A1 &a1, const A2 &a2, const A3 &a3) const
00152   {
00153     try
00154     {
00155       Protect_FPU_rounding<Protection> P;
00156       FC_result_type fr = Filter_construction(To_Filtered(a1),To_Filtered(a2),To_Filtered(a3));
00157       if ( fr )
00158         return From_Filtered(fr);
00159     }
00160     catch (Uncertain_conversion_exception) {}
00161     
00162     Protect_FPU_rounding<!Protection> P(CGAL_FE_TONEAREST);
00163     EC_result_type er = Exact_construction(To_Exact(a1), To_Exact(a2), To_Exact(a3)) ;
00164     return From_Exact(er);
00165 
00166   }
00167   
00168   template <class A1, class A2, class A3, class A4>
00169   result_type
00170   operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4) const
00171   {
00172     try
00173     {
00174       Protect_FPU_rounding<Protection> P;
00175       FC_result_type fr = Filter_construction(To_Filtered(a1),To_Filtered(a2),To_Filtered(a3),To_Filtered(a4));
00176       if ( fr )
00177         return From_Filtered(fr);
00178     }
00179     catch (Uncertain_conversion_exception) {}
00180     
00181     Protect_FPU_rounding<!Protection> P(CGAL_FE_TONEAREST);
00182     EC_result_type er = Exact_construction(To_Exact(a1), To_Exact(a2), To_Exact(a3), To_Exact(a4)) ;
00183     return From_Exact(er);
00184 
00185   }
00186   
00187   template <class A1, class A2, class A3, class A4, class A5>
00188   result_type
00189   operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5) const
00190   {
00191     try
00192     {
00193       Protect_FPU_rounding<Protection> P;
00194       FC_result_type fr = Filter_construction(To_Filtered(a1),To_Filtered(a2),To_Filtered(a3),To_Filtered(a4),To_Filtered(a5));
00195       if ( fr )
00196         return From_Filtered(fr);
00197     }
00198     catch (Uncertain_conversion_exception) {}
00199     
00200     Protect_FPU_rounding<!Protection> P(CGAL_FE_TONEAREST);
00201     EC_result_type er = Exact_construction(To_Exact(a1), To_Exact(a2), To_Exact(a3), To_Exact(a4), To_Exact(a5)) ;
00202     return From_Exact(er);
00203 
00204   }
00205 };
00206 
00207 
00208 //
00209 // This number type is provided because unlike Quotient<> is allows you to create it
00210 // with a zero denominator. Of course you can't evaluate it in that case, but is convenient because it allows client code
00211 // to handle the "error" itself, which in this context is useful.
00212 //
00213 template<class NT>
00214 class Rational
00215 {
00216   public:
00217 
00218     Rational( NT aN, NT aD ) : mN(aN), mD(aD) {}
00219 
00220     NT n() const { return mN ; }
00221     NT d() const { return mD ; }
00222 
00223     CGAL::Quotient<NT> to_quotient() const { return CGAL::Quotient<NT>(mN,mD) ; }
00224     
00225     NT to_nt() const { return mN / mD ; }
00226 
00227     friend std::ostream& operator << ( std::ostream& os, Rational<NT> const& rat )
00228     {
00229       if ( ! CGAL_NTS is_zero(rat.d()) )
00230            return os << n2str(rat.n()/rat.d());
00231       else return os << "INF_RATIONAL" ;
00232     }
00233 
00234   private:
00235 
00236     NT mN, mD ;
00237 } ;
00238 
00239 
00240 //
00241 // A straight skeleton event is the simultaneous coallision of 3 ore    ffseted oriented straight line segments
00242 // e0*,e1*,e2* [e* denotes an _offseted_ edge].
00243 //
00244 // A straight skeleton event is the simultaneous coallision of 3 ore    
00245 //
00246 // This record stores the segments corresponding to the INPUT edges (e0,e1,e2) whose offsets intersect
00247 // at the event along with their collinearity.
00248 //
00249 // If the event is a an edge-event, then e0*->e1*->e2* must be consecutive right before the event so that
00250 // after the event e0* and e2* become consecutive. Thus, there are _offset_ vertices (e0*,e1*) and (e1*,e2*) 
00251 // in the offset polygon which not neccesarily exist in the original polygon.
00252 //
00253 // If the event is a split-event, e0*->e1* must be consecutive right before the event so that after the event
00254 // e0*->right(e2*) and left(e2*)->e1* become consecutive. Thus, there is an offset vertex (e0*,e1*) in the
00255 // offset polygon which not neccesarily exist in the original polygon.
00256 // 
00257 // The offset vertices (e0*,e1*) and (e1*,e2*) are called the left and right seeds for the event.
00258 // A seed is a contour node if the vertex is already present in the input polygon, otherwise is a skeleton node.
00259 // If a seed is a skeleton node is produced by a previous event so it is itself defined as a trisegment, thus,
00260 // a trisegment is actually a node in a binary tree.
00261 // Since trisegments are tree nodes they must always be handled via the nested smart pointer type: Self_ptr.
00262 //
00263 template<class K>
00264 class Trisegment_2 : public Ref_counted_base
00265 {
00266 public:
00267 
00268   typedef typename K::Segment_2 Segment_2 ;
00269     
00270   typedef intrusive_ptr<Trisegment_2> Self_ptr ;
00271   
00272 public:
00273 
00274   Trisegment_2 ( Segment_2 const&        aE0
00275                , Segment_2 const&        aE1
00276                , Segment_2 const&        aE2
00277                , Trisegment_collinearity aCollinearity 
00278                ) 
00279   {
00280     mCollinearity = aCollinearity ;
00281     
00282     mE[0] = aE0 ;
00283     mE[1] = aE1 ;
00284     mE[2] = aE2 ;
00285     
00286     switch ( mCollinearity )
00287     {
00288       case TRISEGMENT_COLLINEARITY_01:
00289         mCSIdx=0; mNCSIdx=2; break ;
00290         
00291       case TRISEGMENT_COLLINEARITY_12:
00292         mCSIdx=1; mNCSIdx=0; break ;
00293         
00294       case TRISEGMENT_COLLINEARITY_02:
00295         mCSIdx=0; mNCSIdx=1; break ;
00296         
00297       case TRISEGMENT_COLLINEARITY_ALL:
00298         mCSIdx=-1; mNCSIdx=-1; break ;
00299         
00300       case TRISEGMENT_COLLINEARITY_NONE:
00301         mCSIdx=-1; mNCSIdx=-1; break ;
00302     }
00303   }
00304     
00305   static Trisegment_2 null() { return Self_ptr() ; }
00306   
00307   Trisegment_collinearity collinearity() const { return mCollinearity ; }
00308 
00309   Segment_2 const& e( unsigned idx ) const { CGAL_precondition(idx<3) ; return mE[idx] ; }
00310   
00311   Segment_2 const& e0() const { return e(0) ; }
00312   Segment_2 const& e1() const { return e(1) ; }
00313   Segment_2 const& e2() const { return e(2) ; }
00314 
00315   // If 2 out of the 3 edges are collinear they can be reclassified as 1 collinear edge (any of the 2) and 1 non-collinear.
00316   // These methods returns the edges according to that classification.
00317   // PRECONDITION: Exactly 2 out of 3 edges are collinear
00318   Segment_2 const& collinear_edge    () const { return e(mCSIdx) ; }
00319   Segment_2 const& non_collinear_edge() const { return e(mNCSIdx) ; }
00320 
00321   Self_ptr child_l() const { return mChildL ; }
00322   Self_ptr child_r() const { return mChildR ; } 
00323   
00324   void set_child_l( Self_ptr const& aChild ) { mChildL = aChild ; }
00325   void set_child_r( Self_ptr const& aChild ) { mChildR = aChild ; }
00326   
00327   enum SEED_ID { LEFT, RIGHT, UNKNOWN } ;
00328       
00329   // Indicates which of the seeds is collinear for a normal collinearity case.
00330   // PRECONDITION: The collinearity is normal.
00331   SEED_ID degenerate_seed_id() const
00332   {
00333     Trisegment_collinearity c = collinearity();
00334       
00335     return c == TRISEGMENT_COLLINEARITY_01 ? LEFT : c == TRISEGMENT_COLLINEARITY_12 ? RIGHT : UNKNOWN  ; 
00336   }
00337 
00338   friend std::ostream& operator << ( std::ostream& os, Trisegment_2<K> const& aTrisegment )
00339   {
00340     return os << "[" << s2str(aTrisegment.e0())
00341               << " " << s2str(aTrisegment.e1())
00342               << " " << s2str(aTrisegment.e2())
00343               << " " << trisegment_collinearity_to_string(aTrisegment.collinearity()) 
00344               << "]";
00345   }
00346   
00347   friend std::ostream& operator << ( std::ostream& os, Self_ptr const& aPtr )
00348   {
00349     recursive_print(os,aPtr,0);
00350     return os ;
00351   }
00352     
00353   static void recursive_print ( std::ostream& os, Self_ptr const& aTriPtr, int aDepth )
00354   {
00355     os << "\n" ;
00356     
00357     for ( int i = 0 ; i < aDepth ; ++ i )
00358       os << "  " ;
00359       
00360     if ( aTriPtr )
00361          os << *aTriPtr ;
00362     else os << "{null}" ;
00363     
00364     if ( aTriPtr->child_l() )
00365       recursive_print(os,aTriPtr->child_l(),aDepth+1);
00366       
00367     if ( aTriPtr->child_r() )
00368       recursive_print(os,aTriPtr->child_r(),aDepth+1);
00369   }
00370   
00371 private :
00372     
00373   Segment_2               mE[3];
00374   Trisegment_collinearity mCollinearity ;
00375   unsigned                mCSIdx, mNCSIdx ;
00376   
00377   Self_ptr mChildL ;
00378   Self_ptr mChildR ;
00379 } ;
00380 
00381 template<class K>
00382 struct Functor_base_2
00383 {
00384   typedef typename K::FT        FT ;
00385   typedef typename K::Point_2   Point_2 ;
00386   typedef typename K::Segment_2 Segment_2 ;
00387   
00388   typedef CGAL_SS_i::Trisegment_2<K> Trisegment_2 ;
00389   
00390   typedef typename Trisegment_2::Self_ptr Trisegment_2_ptr ;
00391 };
00392 
00393 template<class Converter>
00394 struct SS_converter : Converter
00395 {
00396   typedef typename Converter::Source_kernel Source_kernel;
00397   typedef typename Converter::Target_kernel Target_kernel;
00398 
00399   typedef typename Source_kernel::FT Source_FT ;
00400   typedef typename Target_kernel::FT Target_FT ;
00401 
00402   typedef typename Source_kernel::Point_2 Source_point_2 ;
00403   typedef typename Target_kernel::Point_2 Target_point_2 ;
00404 
00405   typedef typename Source_kernel::Segment_2 Source_segment_2 ;
00406   typedef typename Target_kernel::Segment_2 Target_segment_2 ;
00407 
00408   typedef Trisegment_2<Source_kernel> Source_trisegment_2 ;
00409   typedef Trisegment_2<Target_kernel> Target_trisegment_2 ;
00410 
00411   typedef boost::tuple<Source_FT,Source_point_2> Source_time_and_point_2 ;
00412   typedef boost::tuple<Target_FT,Target_point_2> Target_time_and_point_2 ;
00413   
00414   typedef boost::optional<Source_FT> Source_opt_FT ;
00415   typedef boost::optional<Target_FT> Target_opt_FT ;
00416   
00417   typedef boost::optional<Source_point_2> Source_opt_point_2 ;
00418   typedef boost::optional<Target_point_2> Target_opt_point_2 ;
00419   
00420   typedef boost::optional<Source_time_and_point_2> Source_opt_time_and_point_2 ;
00421   typedef boost::optional<Target_time_and_point_2> Target_opt_time_and_point_2 ;
00422   
00423   typedef boost::optional<Source_segment_2> Source_opt_segment_2 ;
00424   typedef boost::optional<Target_segment_2> Target_opt_segment_2 ;
00425   
00426   typedef typename Source_trisegment_2::Self_ptr Source_trisegment_2_ptr ;
00427   typedef typename Target_trisegment_2::Self_ptr Target_trisegment_2_ptr ;
00428   
00429   
00430   Target_FT cvt_n(Source_FT const& n) const  { return this->Converter::operator()(n); }
00431 
00432   Target_opt_FT cvt_n(Source_opt_FT const& n) const
00433   { 
00434     Target_opt_FT r ; 
00435     if ( n ) 
00436       r = cvt_n(*n);
00437     return r ;  
00438   }
00439   
00440   Target_point_2   cvt_p(Source_point_2 const& p) const  { return this->Converter::operator()(p); }
00441 
00442   Target_segment_2 cvt_s( Source_segment_2 const& e) const { return Target_segment_2(cvt_p(e.source()), cvt_p(e.target()) ) ; }
00443   
00444   Target_time_and_point_2 cvt_t_p( Source_time_and_point_2 const& v ) const
00445   {
00446     Source_FT      t ;
00447     Source_point_2 p ;
00448     boost::tie(t,p) = v ;
00449     return Target_time_and_point_2(cvt_n(t),cvt_p(p));
00450   }
00451   
00452   Target_trisegment_2_ptr cvt_single_trisegment( Source_trisegment_2_ptr const& tri ) const
00453   {
00454     CGAL_precondition( tri ) ;
00455     
00456     return Target_trisegment_2_ptr ( new Target_trisegment_2(cvt_s(tri->e0())
00457                                                             ,cvt_s(tri->e1())
00458                                                             ,cvt_s(tri->e2())
00459                                                             ,tri->collinearity()
00460                                                             )
00461                                    ) ;
00462   }
00463   
00464   Target_trisegment_2_ptr cvt_trisegment( Source_trisegment_2_ptr const& tri ) const
00465   {
00466     Target_trisegment_2_ptr res ;
00467     
00468     if ( tri )
00469     {
00470       res = cvt_single_trisegment(tri) ;
00471       
00472       if ( tri->child_l() )
00473         res->set_child_l( cvt_trisegment(tri->child_l()) ) ;
00474         
00475       if ( tri->child_r() )
00476         res->set_child_r( cvt_trisegment(tri->child_r() ) ) ;
00477     }
00478       
00479     return res ;
00480   }
00481   
00482   bool operator()( bool v ) const { return v ; }
00483   
00484   Trisegment_collinearity  operator()(Trisegment_collinearity c) const { return c ; }
00485   
00486   Oriented_side operator()(Oriented_side s) const { return s ; }
00487   
00488   Target_FT        operator()(Source_FT const& n) const { return cvt_n(n) ; }
00489 
00490   Target_opt_FT    operator()(Source_opt_FT const& n) const { return cvt_n(n) ; }
00491   
00492   Target_point_2   operator()( Source_point_2 const& p) const { return cvt_p(p) ; }
00493 
00494   Target_segment_2 operator()( Source_segment_2 const& s) const { return cvt_s(s); }
00495   
00496   Target_trisegment_2_ptr operator()( Source_trisegment_2_ptr const& tri ) const
00497   {
00498     return cvt_trisegment(tri);
00499   }
00500   
00501   Target_time_and_point_2 operator() ( Source_time_and_point_2 const& v ) const
00502   {
00503     return cvt_t_p(v);
00504   }
00505   
00506   Target_opt_point_2 operator()( Source_opt_point_2 const& p) const 
00507   {
00508     if ( p ) 
00509          return Target_opt_point_2(cvt_p(*p));
00510     else return Target_opt_point_2();
00511   }
00512 
00513   Target_opt_segment_2 operator()( Source_opt_segment_2 const& s) const 
00514   {
00515     if ( s ) 
00516          return Target_opt_segment_2(cvt_s(*s));
00517     else return Target_opt_segment_2();
00518   }
00519   
00520   Target_opt_time_and_point_2 operator()( Source_opt_time_and_point_2 const& v) const 
00521   { 
00522     if ( v ) 
00523          return Target_opt_time_and_point_2(cvt_t_p(*v));
00524     else return Target_opt_time_and_point_2();
00525   }
00526   
00527 };
00528 
00529 } // namespace CGAL_SS_i
00530 
00531 
00532 //
00533 // This macro defines a global functor adapter which allows users to use it in the followig ways:
00534 //
00535 // Given a 'Functor' provided by a given 'Traits' (or Kernel):
00536 //
00537 //   typedef typename CGAL::Functor<Traits>::type Functor ;
00538 //   result r = CGAL::Functor<Traits>(traits)(a,b,c);
00539 //
00540 #define CGAL_STRAIGHT_SKELETON_CREATE_FUNCTOR_ADAPTER(functor) \
00541         template<class K> \
00542         typename K :: functor functor ( K const& aK ) \
00543         { \
00544           return aK.get((typename K :: functor const*)0);  \
00545         }
00546 
00547 
00548 CGAL_END_NAMESPACE
00549 
00550 
00551 #endif // CGAL_STRAIGHT_SKELETON_BUILDER_TRAITS_2_AUX_H //
00552 
00553 // EOF //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines