BWAPI
|
00001 // Copyright (c) 2005-2008 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/Polygon_offset_builder_traits_2.h $ 00014 // $Id: Polygon_offset_builder_traits_2.h 46477 2008-10-25 13:48:37Z afabri $ 00015 // 00016 // Author(s) : Fernando Cacciola <fernando_cacciola@ciudad.com.ar> 00017 #ifndef CGAL_POLYGON_OFFSET_BUILDER_TRAITS_2_H 00018 #define CGAL_POLYGON_OFFSET_BUILDER_TRAITS_2_H 1 00019 00020 #include <CGAL/Straight_skeleton_2/Straight_skeleton_aux.h> 00021 #include <CGAL/Straight_skeleton_2/Straight_skeleton_builder_traits_2_aux.h> 00022 #include <CGAL/Straight_skeleton_builder_traits_2.h> 00023 #include <CGAL/predicates/Polygon_offset_pred_ftC2.h> 00024 #include <CGAL/constructions/Polygon_offset_cons_ftC2.h> 00025 #include <CGAL/Exact_predicates_exact_constructions_kernel.h> 00026 00027 #include "boost/type_traits/is_same.hpp" 00028 #include "boost/mpl/if.hpp" 00029 #include "boost/mpl/or.hpp" 00030 00031 CGAL_BEGIN_NAMESPACE 00032 00033 namespace CGAL_SS_i { 00034 00035 template<class K> struct Has_inexact_constructions 00036 { 00037 typedef typename K::FT FT ; 00038 00039 typedef typename boost::mpl::if_< boost::mpl::or_< boost::is_same<FT,double> 00040 , boost::is_same<FT,Interval_nt_advanced> 00041 > 00042 , Tag_true 00043 , Tag_false 00044 >::type type ; 00045 } ; 00046 00047 template<class K> 00048 struct Compare_offset_against_event_time_2 : Functor_base_2<K> 00049 { 00050 typedef Functor_base_2<K> Base ; 00051 00052 typedef typename Base::FT FT ; 00053 typedef typename Base::Segment_2 Segment_2 ; 00054 typedef typename Base::Trisegment_2_ptr Trisegment_2_ptr ; 00055 00056 typedef Uncertain<Comparison_result> result_type ; 00057 00058 Uncertain<Comparison_result> operator() ( FT const& aT, Trisegment_2_ptr const& aE ) const 00059 { 00060 return compare_offset_against_isec_timeC2(aT,aE) ; 00061 } 00062 }; 00063 00064 00065 template<class K> 00066 struct Construct_offset_point_2 : Functor_base_2<K> 00067 { 00068 typedef Functor_base_2<K> Base ; 00069 00070 typedef typename Base::FT FT ; 00071 typedef typename Base::Point_2 Point_2 ; 00072 typedef typename Base::Segment_2 Segment_2 ; 00073 typedef typename Base::Trisegment_2_ptr Trisegment_2_ptr ; 00074 00075 typedef boost::optional<Point_2> result_type ; 00076 00077 00078 result_type operator() ( FT const& aT 00079 , Segment_2 const& aE0 00080 , Segment_2 const& aE1 00081 , Trisegment_2_ptr const& aNode 00082 ) const 00083 { 00084 typename Has_inexact_constructions<K>::type has_inexact_constructions 00085 CGAL_SUNPRO_INITIALIZE( = typename Has_inexact_constructions<K>::type()) ; 00086 00087 return calc(aT, aE0, aE1, aNode, has_inexact_constructions); 00088 } 00089 00090 result_type calc ( FT const& aT 00091 , Segment_2 const& aE0 00092 , Segment_2 const& aE1 00093 , Trisegment_2_ptr const& aNode 00094 , Tag_false // kernel already has exact constructions 00095 ) const 00096 { 00097 result_type p = construct_offset_pointC2(aT,aE0,aE1,aNode); 00098 00099 CGAL_stskel_intrinsic_test_assertion(!p || (p && !is_point_calculation_clearly_wrong(aT,*p,aE0,aE1))); 00100 00101 return p ; 00102 } 00103 00104 result_type calc ( FT const& aT 00105 , Segment_2 const& aE0 00106 , Segment_2 const& aE1 00107 , Trisegment_2_ptr const& aNode 00108 , Tag_true // kernel does not provides exact constructions 00109 ) const 00110 { 00111 typedef Exact_predicates_exact_constructions_kernel EK ; 00112 00113 typedef Cartesian_converter<K,EK> BaseC2E; 00114 typedef Cartesian_converter<EK,K> BaseE2C; 00115 00116 SS_converter<BaseC2E> C2E ; 00117 SS_converter<BaseE2C> E2C ; 00118 00119 result_type p = E2C(construct_offset_pointC2(C2E(aT),C2E(aE0),C2E(aE1),C2E(aNode))); 00120 00121 CGAL_stskel_intrinsic_test_assertion(!p || (p && !is_point_calculation_clearly_wrong(aT,*p,aE0,aE1))); 00122 00123 return p ; 00124 } 00125 00126 bool is_point_calculation_clearly_wrong( FT const& t, Point_2 const& p, Segment_2 const& aE0, Segment_2 const& aE1 ) const 00127 { 00128 bool rR = false ; 00129 00130 if ( is_possibly_inexact_time_clearly_not_zero(t) ) 00131 { 00132 Point_2 const& e0s = aE0.source(); 00133 Point_2 const& e0t = aE0.target(); 00134 00135 Point_2 const& e1s = aE1.source(); 00136 Point_2 const& e1t = aE1.target(); 00137 00138 FT const very_short(0.1); 00139 FT const very_short_squared = CGAL_NTS square(very_short); 00140 00141 FT l0 = squared_distance(e0s,e0t) ; 00142 FT l1 = squared_distance(e1s,e1t) ; 00143 00144 bool e0_is_not_very_short = l0 > very_short_squared ; 00145 bool e1_is_not_very_short = l1 > very_short_squared ; 00146 00147 FT d0 = squared_distance_from_point_to_lineC2(p.x(),p.y(),e0s.x(),e0s.y(),e0t.x(),e0t.y()).to_nt(); 00148 FT d1 = squared_distance_from_point_to_lineC2(p.x(),p.y(),e1s.x(),e1s.y(),e1t.x(),e1t.y()).to_nt(); 00149 00150 FT tt = CGAL_NTS square(t) ; 00151 00152 bool e0_is_clearly_wrong = e0_is_not_very_short && is_possibly_inexact_distance_clearly_not_equal_to(d0,tt) ; 00153 bool e1_is_clearly_wrong = e1_is_not_very_short && is_possibly_inexact_distance_clearly_not_equal_to(d1,tt) ; 00154 00155 bool rR = e0_is_clearly_wrong || e1_is_clearly_wrong ; 00156 00157 CGAL_stskel_intrinsic_test_trace_if(rR 00158 , "\nOffset point calculation is clearly wrong:" 00159 << "\ntime=" << t << " p=" << p2str(p) << " e0=" << s2str(aE0) << " e1=" << s2str(aE1) 00160 << "\nl0=" << inexact_sqrt(l0) << " l1=" << inexact_sqrt(l1) 00161 << "\nd0=" << d0 << " d1=" << d1 << " tt=" << tt 00162 ) ; 00163 } 00164 00165 return rR ; 00166 } 00167 }; 00168 00169 00170 } // namespace CGAL_SS_i 00171 00172 template<class K> 00173 struct Polygon_offset_builder_traits_2_functors 00174 { 00175 typedef CGAL_SS_i::Compare_offset_against_event_time_2<K> Compare_offset_against_event_time_2 ; 00176 typedef CGAL_SS_i::Compare_ss_event_times_2 <K> Compare_ss_event_times_2 ; 00177 typedef CGAL_SS_i::Construct_offset_point_2 <K> Construct_offset_point_2 ; 00178 typedef CGAL_SS_i::Construct_ss_trisegment_2 <K> Construct_ss_trisegment_2 ; 00179 typedef CGAL_SS_i::Construct_ss_event_time_and_point_2<K> Construct_ss_event_time_and_point_2 ; 00180 } ; 00181 00182 template<class K> 00183 struct Polygon_offset_builder_traits_2_base 00184 { 00185 typedef K Kernel ; 00186 00187 typedef typename K::FT FT ; 00188 typedef typename K::Point_2 Point_2 ; 00189 typedef typename K::Segment_2 Segment_2 ; 00190 00191 typedef CGAL_SS_i::Trisegment_2<K> Trisegment_2 ; 00192 00193 typedef typename Trisegment_2::Self_ptr Trisegment_2_ptr ; 00194 00195 template<class F> F get( F const* = 0 ) const { return F(); } 00196 } ; 00197 00198 template<class Is_filtered_kernel, class K> class Polygon_offset_builder_traits_2_impl ; 00199 00200 template<class K> 00201 class Polygon_offset_builder_traits_2_impl<Tag_false,K> : public Polygon_offset_builder_traits_2_base<K> 00202 { 00203 typedef Polygon_offset_builder_traits_2_functors<K> Unfiltering ; 00204 00205 public: 00206 00207 typedef Unfiltered_predicate_adaptor<typename Unfiltering::Compare_offset_against_event_time_2> 00208 Compare_offset_against_event_time_2 ; 00209 00210 typedef Unfiltered_predicate_adaptor<typename Unfiltering::Compare_ss_event_times_2> 00211 Compare_ss_event_times_2 ; 00212 00213 typedef typename Unfiltering::Construct_offset_point_2 Construct_offset_point_2 ; 00214 typedef typename Unfiltering::Construct_ss_trisegment_2 Construct_ss_trisegment_2 ; 00215 typedef typename Unfiltering::Construct_ss_event_time_and_point_2 Construct_ss_event_time_and_point_2 ; 00216 00217 } ; 00218 00219 template<class K> 00220 class Polygon_offset_builder_traits_2_impl<Tag_true,K> : public Polygon_offset_builder_traits_2_base<K> 00221 { 00222 typedef typename K::Exact_kernel EK ; 00223 typedef typename K::Approximate_kernel FK ; 00224 00225 typedef Polygon_offset_builder_traits_2_functors<EK> Exact ; 00226 typedef Polygon_offset_builder_traits_2_functors<FK> Filtering ; 00227 typedef Polygon_offset_builder_traits_2_functors<K> Unfiltering ; 00228 00229 typedef Cartesian_converter<K,EK> BaseC2E; 00230 typedef Cartesian_converter<K,FK> BaseC2F; 00231 typedef Cartesian_converter<EK,K> BaseE2C; 00232 typedef Cartesian_converter<FK,K> BaseF2C; 00233 typedef Cartesian_converter<K,K> BaseC2C; 00234 00235 typedef CGAL_SS_i::SS_converter<BaseC2E> C2E ; 00236 typedef CGAL_SS_i::SS_converter<BaseC2F> C2F ; 00237 typedef CGAL_SS_i::SS_converter<BaseE2C> E2C ; 00238 typedef CGAL_SS_i::SS_converter<BaseF2C> F2C ; 00239 typedef CGAL_SS_i::SS_converter<BaseC2C> C2C ; 00240 00241 public: 00242 00243 typedef Filtered_predicate<typename Exact ::Compare_offset_against_event_time_2 00244 ,typename Filtering::Compare_offset_against_event_time_2 00245 , C2E 00246 , C2F 00247 > 00248 Compare_offset_against_event_time_2 ; 00249 00250 typedef Filtered_predicate< typename Exact ::Compare_ss_event_times_2 00251 , typename Filtering::Compare_ss_event_times_2 00252 , C2E 00253 , C2F 00254 > 00255 Compare_ss_event_times_2 ; 00256 00257 typedef CGAL_SS_i::Exceptionless_filtered_construction< typename Unfiltering::Construct_offset_point_2 00258 , typename Exact ::Construct_offset_point_2 00259 , typename Unfiltering::Construct_offset_point_2 00260 , C2E 00261 , C2C 00262 , E2C 00263 , C2C 00264 > 00265 Construct_offset_point_2 ; 00266 00267 typedef CGAL_SS_i::Exceptionless_filtered_construction< typename Unfiltering::Construct_ss_trisegment_2 00268 , typename Exact ::Construct_ss_trisegment_2 00269 , typename Unfiltering::Construct_ss_trisegment_2 00270 , C2E 00271 , C2C 00272 , E2C 00273 , C2C 00274 > 00275 Construct_ss_trisegment_2 ; 00276 00277 typedef CGAL_SS_i::Exceptionless_filtered_construction< typename Unfiltering::Construct_ss_event_time_and_point_2 00278 , typename Exact ::Construct_ss_event_time_and_point_2 00279 , typename Unfiltering::Construct_ss_event_time_and_point_2 00280 , C2E 00281 , C2C 00282 , E2C 00283 , C2C 00284 > 00285 Construct_ss_event_time_and_point_2 ; 00286 } ; 00287 00288 template<class K> 00289 class Polygon_offset_builder_traits_2 00290 : public Polygon_offset_builder_traits_2_impl<typename CGAL_SS_i::Is_filtering_kernel<K>::type,K> 00291 { 00292 } ; 00293 00294 CGAL_STRAIGHT_SKELETON_CREATE_FUNCTOR_ADAPTER(Compare_offset_against_event_time_2); 00295 CGAL_STRAIGHT_SKELETON_CREATE_FUNCTOR_ADAPTER(Construct_offset_point_2); 00296 00297 CGAL_END_NAMESPACE 00298 00299 00300 #endif // CGAL_POLYGON_OFFSET_BUILDER_TRAITS_2_H // 00301 // EOF //