📄 straight_skeleton_builder_traits_2_aux.h
字号:
// Copyright (c) 2006 Fernando Luis Cacciola Carballal. All rights reserved.//// This file is part of CGAL (www.cgal.org); you may redistribute it under// the terms of the Q Public License version 1.0.// See the file LICENSE.QPL distributed with CGAL.//// Licensees holding a valid commercial license may use this file in// accordance with the commercial license agreement provided with the software.//// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.//// $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.3-branch/Straight_skeleton_2/include/CGAL/Straight_skeleton_2/Straight_skeleton_builder_traits_2_aux.h $// $Id: Straight_skeleton_builder_traits_2_aux.h 36824 2007-03-05 16:42:00Z spion $//// Author(s) : Fernando Cacciola <fernando_cacciola@ciudad.com.ar>//#ifndef CGAL_STRAIGHT_SKELETON_BUILDER_TRAITS_2_AUX_H#define CGAL_STRAIGHT_SKELETON_BUILDER_TRAITS_2_AUX_H 1#include <CGAL/tags.h>#include <CGAL/Handle.h>#include <CGAL/Uncertain.h>#include <CGAL/certified_numeric_predicates.h>#include <CGAL/Quotient.h>#include <CGAL/certified_quotient_predicates.h>#include <CGAL/Unfiltered_predicate_adaptor.h>#include <CGAL/Filtered_predicate.h>#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>#include <boost/tuple/tuple.hpp>#include <boost/intrusive_ptr.hpp>#include <boost/optional/optional.hpp>#include <boost/none.hpp>#ifdef CGAL_STRAIGHT_SKELETON_TRAITS_ENABLE_TRACE# include<string># include<iostream># include<sstream># include<iomanip>bool sEnableTraitsTrace = false ;# define CGAL_STSKEL_TRAITS_ENABLE_TRACE sEnableTraitsTrace = true ;# define CGAL_STSKEL_TRAITS_ENABLE_TRACE_IF(cond) if ((cond)) sEnableTraitsTrace = true ;# define CGAL_STSKEL_TRAITS_DISABLE_TRACE sEnableTraitsTrace = false;# define CGAL_STSKEL_TRAITS_TRACE(m) \ if ( sEnableTraitsTrace ) \ { \ std::ostringstream ss ; \ ss << m ; \ std::string s = ss.str(); \ Straight_skeleton_traits_external_trace(s); \ }#else# define CGAL_STSKEL_TRAITS_ENABLE_TRACE# define CGAL_STSKEL_TRAITS_ENABLE_TRACE_IF(cond)# define CGAL_STSKEL_TRAITS_DISABLE_TRACE# define CGAL_STSKEL_TRAITS_TRACE(m)#endifCGAL_BEGIN_NAMESPACEnamespace CGAL_SS_i {using boost::optional ;// boost::make_optional is provided in Boost >= 1.34, but not before, so we define our own versions here.template<class T> optional<T> cgal_make_optional( T const& v ) { return optional<T>(v) ; }template<class T> optional<T> cgal_make_optional( bool cond, T const& v ) { return cond ? optional<T>(v) : optional<T>() ; }template<class K>struct Is_filtering_kernel{ typedef Tag_false type ;} ;template<>struct Is_filtering_kernel< Exact_predicates_inexact_constructions_kernel >{ typedef Tag_true type ;} ;//// This is the same as Filtered_construction but uses optional<result> instead of exceptions.//template <class AC ,class EC ,class FC ,class C2E ,class C2F ,class E2C ,class F2C ,bool Protection = true>class Exceptionless_filtered_construction{private: EC Exact_construction; FC Filter_construction; C2E To_Exact; C2F To_Filtered; E2C From_Exact; F2C From_Filtered; typedef typename AC::result_type AC_result_type; typedef typename FC::result_type FC_result_type; typedef typename EC::result_type EC_result_type;public: typedef AC_result_type result_type; typedef typename AC::Arity Arity;public: Exceptionless_filtered_construction() {} template <class A1> result_type operator()(const A1 &a1) const { try { Protect_FPU_rounding<Protection> P; FC_result_type fr = Filter_construction(To_Filtered(a1)); if ( fr ) return From_Filtered(fr); } catch (Interval_nt_advanced::unsafe_comparison) {} Protect_FPU_rounding<!Protection> P(CGAL_FE_TONEAREST); EC_result_type er = Exact_construction(To_Exact(a1)) ; return From_Exact(er); } template <class A1, class A2> result_type operator()(const A1 &a1, const A2 &a2) const { try { Protect_FPU_rounding<Protection> P; FC_result_type fr = Filter_construction(To_Filtered(a1),To_Filtered(a2)); if ( fr ) return From_Filtered(fr); } catch (Interval_nt_advanced::unsafe_comparison) {} Protect_FPU_rounding<!Protection> P(CGAL_FE_TONEAREST); EC_result_type er = Exact_construction(To_Exact(a1), To_Exact(a2)) ; return From_Exact(er); } template <class A1, class A2, class A3> result_type operator()(const A1 &a1, const A2 &a2, const A3 &a3) const { try { Protect_FPU_rounding<Protection> P; FC_result_type fr = Filter_construction(To_Filtered(a1),To_Filtered(a2),To_Filtered(a3)); if ( fr ) return From_Filtered(fr); } catch (Interval_nt_advanced::unsafe_comparison) {} Protect_FPU_rounding<!Protection> P(CGAL_FE_TONEAREST); EC_result_type er = Exact_construction(To_Exact(a1), To_Exact(a2), To_Exact(a3)) ; return From_Exact(er); } template <class A1, class A2, class A3, class A4> result_type operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4) const { try { Protect_FPU_rounding<Protection> P; FC_result_type fr = Filter_construction(To_Filtered(a1),To_Filtered(a2),To_Filtered(a3),To_Filtered(a4)); if ( fr ) return From_Filtered(fr); } catch (Interval_nt_advanced::unsafe_comparison) {} Protect_FPU_rounding<!Protection> P(CGAL_FE_TONEAREST); EC_result_type er = Exact_construction(To_Exact(a1), To_Exact(a2), To_Exact(a3), To_Exact(a4)) ; return From_Exact(er); } template <class A1, class A2, class A3, class A4, class A5> result_type operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5) const { try { Protect_FPU_rounding<Protection> P; FC_result_type fr = Filter_construction(To_Filtered(a1),To_Filtered(a2),To_Filtered(a3),To_Filtered(a4),To_Filtered(a5)); if ( fr ) return From_Filtered(fr); } catch (Interval_nt_advanced::unsafe_comparison) {} Protect_FPU_rounding<!Protection> P(CGAL_FE_TONEAREST); EC_result_type er = Exact_construction(To_Exact(a1), To_Exact(a2), To_Exact(a3), To_Exact(a4), To_Exact(a5)) ; return From_Exact(er); }};//// This number type is provided because unlike Quotient<> is allows you to create it// with a zero denominator. Of course you can't evaluate it in that case, but is convenient because it allows client code// to handle the "error" itself, which in this context is useful.//template<class NT>class Rational{ public: Rational( NT aN, NT aD ) : mN(aN), mD(aD) {} NT n() const { return mN ; } NT d() const { return mD ; } CGAL::Quotient<NT> to_quotient() const { return CGAL::Quotient<NT>(mN,mD) ; } friend std::ostream& operator << ( std::ostream& os, Rational<NT> const& rat ) { if ( ! CGAL_NTS is_zero(rat.d()) ) return os << n2str(rat.n()/rat.d()); else return os << "INF_RATIONAL" ; } private: NT mN, mD ;} ;//// A straight skeleton event is the simultaneous coallision of 3 offseted oriented straight line segments// e0*,e1*,e2* [e* denotes an _offseted_ edge].//// This record stores the segments corresponding to the INPUT edges (e0,e1,e2) whose offsets intersect// at the event along with their collinearity.//// If the event is a an edge-event, then e0*->e1*->e2* must be consecutive right before the event so that// after the event e0* and e2* become consecutive. Thus, there are _offset_ vertices (e0*,e1*) and (e1*,e2*) // in the offset polygon which not neccesarily exist in the original polygon.//// If the event is a split-event, e0*->e1* must be consecutive right before the event so that after the event// e0*->right(e2*) and left(e2*)->e1* become consecutive. Thus, there is an offset vertex (e0*,e1*) in the// offset polygon which not neccesarily exist in the original polygon.// // The offset vertices (e0*,e1*) and (e1*,e2*) are called the left and right seeds for the event.// A seed is a contour node if the vertex is already present in the input polygon, otherwise is a skeleton node.// If a seed is a skeleton node is produced by an event so it is itself defined as a trisegment.//// A default constructed trisegment is formally defined a null trisegment.//template<class K>class Trisegment_2{ public: typedef typename K::Segment_2 Segment_2 ; public: Trisegment_2() : mRep(0) {} Trisegment_2( Segment_2 const& aE0 , Segment_2 const& aE1 , Segment_2 const& aE2 , Trisegment_collinearity aCollinearity ) : mRep( new Rep(aE0,aE1,aE2,aCollinearity) ) {} static Trisegment_2 null() { return Trisegment_2() ; } Trisegment_collinearity collinearity() const { return rep().mCollinearity ; } Segment_2 const& e( unsigned idx ) const { CGAL_precondition(idx<3) ; return rep().mE[idx] ; } Segment_2 const& e0() const { return e(0) ; } Segment_2 const& e1() const { return e(1) ; } Segment_2 const& e2() const { return e(2) ; } // 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.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -