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/Straight_skeleton_builder_traits_2.h $ 00014 // $Id: Straight_skeleton_builder_traits_2.h 46477 2008-10-25 13:48:37Z afabri $ 00015 // 00016 // Author(s) : Fernando Cacciola <fernando_cacciola@ciudad.com.ar> 00017 // 00018 #ifndef CGAL_STRAIGHT_SKELETON_BUILDER_TRAITS_2_H 00019 #define CGAL_STRAIGHT_SKELETON_BUILDER_TRAITS_2_H 1 00020 00021 #include <CGAL/Filtered_construction.h> 00022 #include <CGAL/Straight_skeleton_2/Straight_skeleton_aux.h> 00023 #include <CGAL/Straight_skeleton_2/Straight_skeleton_builder_traits_2_aux.h> 00024 #include <CGAL/predicates/Straight_skeleton_pred_ftC2.h> 00025 #include <CGAL/constructions/Straight_skeleton_cons_ftC2.h> 00026 00027 CGAL_BEGIN_NAMESPACE 00028 00029 namespace CGAL_SS_i { 00030 00031 00032 template<class K> 00033 struct Construct_ss_trisegment_2 : Functor_base_2<K> 00034 { 00035 typedef Functor_base_2<K> Base ; 00036 00037 typedef typename Base::Segment_2 Segment_2 ; 00038 typedef typename Base::Trisegment_2 Trisegment_2 ; 00039 typedef typename Base::Trisegment_2_ptr Trisegment_2_ptr ; 00040 00041 typedef Trisegment_2_ptr result_type ; 00042 00043 00044 result_type operator() () const { return cgal_make_optional( Trisegment_2::null() ) ; } 00045 00046 result_type operator() ( Segment_2 const& aS0, Segment_2 const& aS1, Segment_2 const& aS2 ) const 00047 { 00048 return construct_trisegment(aS0,aS1,aS2); 00049 } 00050 }; 00051 00052 template<class K> 00053 struct Do_ss_event_exist_2 : Functor_base_2<K> 00054 { 00055 typedef Functor_base_2<K> Base ; 00056 00057 typedef typename Base::FT FT ; 00058 typedef typename Base::Trisegment_2_ptr Trisegment_2_ptr ; 00059 00060 typedef Uncertain<bool> result_type ; 00061 00062 Uncertain<bool> operator() ( Trisegment_2_ptr const& aTrisegment, boost::optional<FT> aMaxTime ) const 00063 { 00064 Uncertain<bool> rResult = exist_offset_lines_isec2(aTrisegment,aMaxTime) ; 00065 00066 CGAL_STSKEL_ASSERT_PREDICATE_RESULT(rResult,K,"Exist_event",aTrisegment); 00067 00068 return rResult ; 00069 } 00070 }; 00071 00072 template<class K> 00073 struct Is_edge_facing_ss_node_2 : Functor_base_2<K> 00074 { 00075 typedef Functor_base_2<K> Base ; 00076 00077 typedef typename Base::Point_2 Point_2 ; 00078 typedef typename Base::Segment_2 Segment_2 ; 00079 typedef typename Base::Trisegment_2_ptr Trisegment_2_ptr ; 00080 00081 typedef Uncertain<bool> result_type ; 00082 00083 Uncertain<bool> operator() ( Point_2 const& aContourNode, Segment_2 const& aEdge ) const 00084 { 00085 return is_edge_facing_pointC2(cgal_make_optional(aContourNode),aEdge) ; 00086 } 00087 00088 Uncertain<bool> operator() ( Trisegment_2_ptr const& aSkeletonNode, Segment_2 const& aEdge ) const 00089 { 00090 return is_edge_facing_offset_lines_isecC2(aSkeletonNode,aEdge) ; 00091 } 00092 }; 00093 00094 template<class K> 00095 struct Compare_ss_event_times_2 : Functor_base_2<K> 00096 { 00097 typedef Functor_base_2<K> Base ; 00098 00099 typedef typename Base::Trisegment_2_ptr Trisegment_2_ptr ; 00100 00101 typedef Uncertain<Comparison_result> result_type ; 00102 00103 Uncertain<Comparison_result> operator() ( Trisegment_2_ptr const& aL, Trisegment_2_ptr const& aR ) const 00104 { 00105 Uncertain<Comparison_result> rResult = compare_offset_lines_isec_timesC2(aL,aR) ; 00106 00107 CGAL_STSKEL_ASSERT_PREDICATE_RESULT(rResult,K,"Compare_event_times","L: " << aL << "\nR:" << aR ); 00108 00109 return rResult ; 00110 } 00111 }; 00112 00113 template<class K> 00114 struct Oriented_side_of_event_point_wrt_bisector_2 : Functor_base_2<K> 00115 { 00116 typedef Functor_base_2<K> Base ; 00117 00118 typedef typename Base::Segment_2 Segment_2 ; 00119 typedef typename Base::Trisegment_2_ptr Trisegment_2_ptr ; 00120 typedef typename Base::Point_2 Point_2 ; 00121 00122 typedef Uncertain<Oriented_side> result_type ; 00123 00124 Uncertain<Oriented_side> operator() ( Trisegment_2_ptr const& aEvent 00125 , Segment_2 const& aE0 00126 , Segment_2 const& aE1 00127 , Trisegment_2_ptr const& aE01Event 00128 , bool aE0isPrimary 00129 ) const 00130 { 00131 Uncertain<Oriented_side> rResult = oriented_side_of_event_point_wrt_bisectorC2(aEvent,aE0,aE1,aE01Event,aE0isPrimary) ; 00132 00133 CGAL_STSKEL_ASSERT_PREDICATE_RESULT(rResult,K,"Oriented_side_of_event_point_wrt_bisector_2","Event=" << aEvent << " E0=" << aE0 << " E1=" << aE1 ); 00134 00135 return rResult ; 00136 } 00137 }; 00138 00139 00140 template<class K> 00141 struct Are_ss_events_simultaneous_2 : Functor_base_2<K> 00142 { 00143 typedef Functor_base_2<K> Base ; 00144 00145 typedef typename Base::Trisegment_2_ptr Trisegment_2_ptr ; 00146 00147 typedef Uncertain<bool> result_type ; 00148 00149 Uncertain<bool> operator() ( Trisegment_2_ptr const& aA, Trisegment_2_ptr const& aB ) const 00150 { 00151 Uncertain<bool> rResult = are_events_simultaneousC2(aA,aB); 00152 00153 CGAL_STSKEL_ASSERT_PREDICATE_RESULT(rResult,K,"Are_events_simultaneous","A=" << aA << "\nB=" << aB); 00154 00155 return rResult ; 00156 } 00157 }; 00158 00159 template<class K> 00160 struct Are_ss_edges_collinear_2 : Functor_base_2<K> 00161 { 00162 typedef Functor_base_2<K> Base ; 00163 00164 typedef typename Base::Segment_2 Segment_2 ; 00165 00166 typedef Uncertain<bool> result_type ; 00167 00168 Uncertain<bool> operator() ( Segment_2 const& aA, Segment_2 const& aB ) const 00169 { 00170 Uncertain<bool> rResult = are_edges_collinearC2(aA,aB); 00171 00172 CGAL_STSKEL_ASSERT_PREDICATE_RESULT(rResult,K,"Are_ss_edges_collinear","A=" << aA << "\nB=" << aB); 00173 00174 return rResult ; 00175 } 00176 }; 00177 00178 template<class K> 00179 struct Are_ss_edges_parallel_2 : Functor_base_2<K> 00180 { 00181 typedef Functor_base_2<K> Base ; 00182 00183 typedef typename Base::Segment_2 Segment_2 ; 00184 00185 typedef Uncertain<bool> result_type ; 00186 00187 Uncertain<bool> operator() ( Segment_2 const& aA, Segment_2 const& aB ) const 00188 { 00189 Uncertain<bool> rResult = are_edges_parallelC2(aA,aB); 00190 00191 CGAL_STSKEL_ASSERT_PREDICATE_RESULT(rResult,K,"Are_ss_edges_parallel","A=" << aA << "\nB=" << aB); 00192 00193 return rResult ; 00194 } 00195 }; 00196 00197 00198 template<class K> 00199 struct Construct_ss_event_time_and_point_2 : Functor_base_2<K> 00200 { 00201 typedef Functor_base_2<K> Base ; 00202 00203 typedef typename Base::FT FT ; 00204 typedef typename Base::Point_2 Point_2 ; 00205 typedef typename Base::Segment_2 Segment_2 ; 00206 typedef typename Base::Trisegment_2_ptr Trisegment_2_ptr ; 00207 00208 typedef boost::tuple<FT,Point_2> rtype ; 00209 00210 typedef boost::optional<rtype> result_type ; 00211 00212 00213 result_type operator() ( Trisegment_2_ptr const& aTrisegment ) const 00214 { 00215 bool lOK = false ; 00216 00217 FT t(0) ; 00218 Point_2 i = ORIGIN ; 00219 00220 optional< Rational<FT> > ot = compute_offset_lines_isec_timeC2(aTrisegment); 00221 00222 if ( !!ot && certainly( CGAL_NTS certified_is_not_zero(ot->d()) ) ) 00223 { 00224 t = ot->n() / ot->d(); 00225 00226 optional<Point_2> oi = construct_offset_lines_isecC2(aTrisegment); 00227 if ( oi ) 00228 { 00229 i = *oi ; 00230 CGAL_stskel_intrinsic_test_assertion(!is_point_calculation_clearly_wrong(t,i,aTrisegment)); 00231 lOK = true ; 00232 } 00233 } 00234 00235 CGAL_STSKEL_ASSERT_CONSTRUCTION_RESULT(lOK,K,"Construct_ss_event_time_and_point_2",aTrisegment); 00236 00237 return cgal_make_optional(lOK,boost::make_tuple(t,i)) ; 00238 } 00239 00240 bool is_point_calculation_clearly_wrong( FT const& t, Point_2 const& p, Trisegment_2_ptr const& aTrisegment ) const 00241 { 00242 bool rR = false ; 00243 00244 if ( is_possibly_inexact_time_clearly_not_zero(t) ) 00245 { 00246 Segment_2 const& e0 = aTrisegment->e0() ; 00247 Segment_2 const& e1 = aTrisegment->e1() ; 00248 Segment_2 const& e2 = aTrisegment->e2() ; 00249 00250 Point_2 const& e0s = e0.source(); 00251 Point_2 const& e0t = e0.target(); 00252 00253 Point_2 const& e1s = e1.source(); 00254 Point_2 const& e1t = e1.target(); 00255 00256 Point_2 const& e2s = e2.source(); 00257 Point_2 const& e2t = e2.target(); 00258 00259 FT const very_short(0.1); 00260 FT const very_short_squared = CGAL_NTS square(very_short); 00261 00262 FT l0 = squared_distance(e0s,e0t) ; 00263 FT l1 = squared_distance(e1s,e1t) ; 00264 FT l2 = squared_distance(e2s,e2t) ; 00265 00266 bool e0_is_not_very_short = l0 > very_short_squared ; 00267 bool e1_is_not_very_short = l1 > very_short_squared ; 00268 bool e2_is_not_very_short = l2 > very_short_squared ; 00269 00270 FT d0 = squared_distance_from_point_to_lineC2(p.x(),p.y(),e0s.x(),e0s.y(),e0t.x(),e0t.y()).to_nt(); 00271 FT d1 = squared_distance_from_point_to_lineC2(p.x(),p.y(),e1s.x(),e1s.y(),e1t.x(),e1t.y()).to_nt(); 00272 FT d2 = squared_distance_from_point_to_lineC2(p.x(),p.y(),e2s.x(),e2s.y(),e2t.x(),e2t.y()).to_nt(); 00273 00274 FT tt = CGAL_NTS square(t); 00275 00276 bool e0_is_clearly_wrong = e0_is_not_very_short && is_possibly_inexact_distance_clearly_not_equal_to(d0,tt) ; 00277 bool e1_is_clearly_wrong = e1_is_not_very_short && is_possibly_inexact_distance_clearly_not_equal_to(d1,tt) ; 00278 bool e2_is_clearly_wrong = e2_is_not_very_short && is_possibly_inexact_distance_clearly_not_equal_to(d2,tt) ; 00279 00280 rR = e0_is_clearly_wrong || e1_is_clearly_wrong || e2_is_clearly_wrong ; 00281 00282 CGAL_stskel_intrinsic_test_trace_if(rR 00283 , "\nSkeleton node point calculation is clearly wrong:" 00284 << "\ntime=" << t << " p=" << p2str(p) << " e0=" << s2str(e0) << " e1=" << s2str(e1) << " e2=" << s2str(e2) 00285 << "\nl0=" << inexact_sqrt(l0) << " l1=" << inexact_sqrt(l1) << " l2=" << inexact_sqrt(l2) 00286 << "\nd0=" << d0 << " d1=" << d1 << " d2=" << d2 << " tt=" << tt 00287 ) ; 00288 } 00289 00290 return rR ; 00291 } 00292 }; 00293 00294 } // namespace CGAL_SS_i 00295 00296 template<class K> 00297 struct Straight_skeleton_builder_traits_2_functors 00298 { 00299 typedef CGAL_SS_i::Do_ss_event_exist_2 <K> Do_ss_event_exist_2 ; 00300 typedef CGAL_SS_i::Compare_ss_event_times_2 <K> Compare_ss_event_times_2 ; 00301 typedef CGAL_SS_i::Is_edge_facing_ss_node_2 <K> Is_edge_facing_ss_node_2 ; 00302 typedef CGAL_SS_i::Oriented_side_of_event_point_wrt_bisector_2<K> Oriented_side_of_event_point_wrt_bisector_2 ; 00303 typedef CGAL_SS_i::Are_ss_events_simultaneous_2 <K> Are_ss_events_simultaneous_2 ; 00304 typedef CGAL_SS_i::Are_ss_edges_parallel_2 <K> Are_ss_edges_parallel_2 ; 00305 typedef CGAL_SS_i::Are_ss_edges_collinear_2 <K> Are_ss_edges_collinear_2 ; 00306 typedef CGAL_SS_i::Construct_ss_event_time_and_point_2 <K> Construct_ss_event_time_and_point_2 ; 00307 typedef CGAL_SS_i::Construct_ss_trisegment_2 <K> Construct_ss_trisegment_2 ; 00308 } ; 00309 00310 template<class K> 00311 struct Straight_skeleton_builder_traits_2_base 00312 { 00313 typedef K Kernel ; 00314 00315 typedef typename K::FT FT ; 00316 typedef typename K::Point_2 Point_2 ; 00317 typedef typename K::Vector_2 Vector_2 ; 00318 typedef typename K::Direction_2 Direction_2 ; 00319 typedef typename K::Segment_2 Segment_2 ; 00320 00321 typedef CGAL_SS_i::Trisegment_2<K> Trisegment_2 ; 00322 00323 typedef typename Trisegment_2::Self_ptr Trisegment_2_ptr ; 00324 00325 template<class F> F get( F const* = 0 ) const { return F(); } 00326 00327 } ; 00328 00329 00330 template<class Is_filtered_kernel, class K> class Straight_skeleton_builder_traits_2_impl ; 00331 00332 template<class K> 00333 class Straight_skeleton_builder_traits_2_impl<Tag_false,K> : public Straight_skeleton_builder_traits_2_base<K> 00334 { 00335 typedef Straight_skeleton_builder_traits_2_functors<K> Unfiltering ; 00336 00337 public: 00338 00339 typedef Unfiltered_predicate_adaptor<typename Unfiltering::Do_ss_event_exist_2> 00340 Do_ss_event_exist_2 ; 00341 00342 typedef Unfiltered_predicate_adaptor<typename Unfiltering::Compare_ss_event_times_2> 00343 Compare_ss_event_times_2 ; 00344 00345 typedef Unfiltered_predicate_adaptor<typename Unfiltering::Is_edge_facing_ss_node_2> 00346 Is_edge_facing_ss_node_2 ; 00347 00348 typedef Unfiltered_predicate_adaptor<typename Unfiltering::Oriented_side_of_event_point_wrt_bisector_2> 00349 Oriented_side_of_event_point_wrt_bisector_2 ; 00350 00351 typedef Unfiltered_predicate_adaptor<typename Unfiltering::Are_ss_events_simultaneous_2> 00352 Are_ss_events_simultaneous_2 ; 00353 00354 typedef Unfiltered_predicate_adaptor<typename Unfiltering::Are_ss_edges_parallel_2> 00355 Are_ss_edges_parallel_2 ; 00356 00357 typedef Unfiltered_predicate_adaptor<typename Unfiltering::Are_ss_edges_collinear_2> 00358 Are_ss_edges_collinear_2 ; 00359 00360 typedef typename Unfiltering::Construct_ss_event_time_and_point_2 Construct_ss_event_time_and_point_2 ; 00361 typedef typename Unfiltering::Construct_ss_trisegment_2 Construct_ss_trisegment_2 ; 00362 } ; 00363 00364 template<class K> 00365 class Straight_skeleton_builder_traits_2_impl<Tag_true,K> : public Straight_skeleton_builder_traits_2_base<K> 00366 { 00367 typedef typename K::Exact_kernel EK ; 00368 typedef typename K::Approximate_kernel FK ; 00369 00370 typedef Straight_skeleton_builder_traits_2_functors<EK> Exact ; 00371 typedef Straight_skeleton_builder_traits_2_functors<FK> Filtering ; 00372 typedef Straight_skeleton_builder_traits_2_functors<K> Unfiltering ; 00373 00374 typedef Cartesian_converter<K,EK> BaseC2E; 00375 typedef Cartesian_converter<K,FK> BaseC2F; 00376 typedef Cartesian_converter<EK,K> BaseE2C; 00377 typedef Cartesian_converter<FK,K> BaseF2C; 00378 typedef Cartesian_converter<K,K> BaseC2C; 00379 00380 typedef CGAL_SS_i::SS_converter<BaseC2E> C2E ; 00381 typedef CGAL_SS_i::SS_converter<BaseC2F> C2F ; 00382 typedef CGAL_SS_i::SS_converter<BaseE2C> E2C ; 00383 typedef CGAL_SS_i::SS_converter<BaseF2C> F2C ; 00384 typedef CGAL_SS_i::SS_converter<BaseC2C> C2C ; 00385 00386 public: 00387 00388 typedef Filtered_predicate<typename Exact ::Do_ss_event_exist_2 00389 ,typename Filtering::Do_ss_event_exist_2 00390 , C2E 00391 , C2F 00392 > 00393 Do_ss_event_exist_2 ; 00394 00395 typedef Filtered_predicate< typename Exact ::Compare_ss_event_times_2 00396 , typename Filtering::Compare_ss_event_times_2 00397 , C2E 00398 , C2F 00399 > 00400 Compare_ss_event_times_2 ; 00401 00402 typedef Filtered_predicate< typename Exact ::Is_edge_facing_ss_node_2 00403 , typename Filtering::Is_edge_facing_ss_node_2 00404 , C2E 00405 , C2F 00406 > 00407 Is_edge_facing_ss_node_2 ; 00408 00409 typedef Filtered_predicate< typename Exact ::Oriented_side_of_event_point_wrt_bisector_2 00410 , typename Filtering::Oriented_side_of_event_point_wrt_bisector_2 00411 , C2E 00412 , C2F 00413 > 00414 Oriented_side_of_event_point_wrt_bisector_2 ; 00415 00416 typedef Filtered_predicate< typename Exact ::Are_ss_events_simultaneous_2 00417 , typename Filtering::Are_ss_events_simultaneous_2 00418 , C2E 00419 , C2F 00420 > 00421 Are_ss_events_simultaneous_2 ; 00422 00423 typedef Filtered_predicate< typename Exact ::Are_ss_edges_parallel_2 00424 , typename Filtering::Are_ss_edges_parallel_2 00425 , C2E 00426 , C2F 00427 > 00428 Are_ss_edges_parallel_2 ; 00429 00430 typedef Filtered_predicate< typename Exact ::Are_ss_edges_collinear_2 00431 , typename Filtering::Are_ss_edges_collinear_2 00432 , C2E 00433 , C2F 00434 > 00435 Are_ss_edges_collinear_2 ; 00436 00437 typedef CGAL_SS_i::Exceptionless_filtered_construction< typename Unfiltering::Construct_ss_event_time_and_point_2 00438 , typename Exact ::Construct_ss_event_time_and_point_2 00439 , typename Unfiltering::Construct_ss_event_time_and_point_2 00440 , C2E 00441 , C2C 00442 , E2C 00443 , C2C 00444 > 00445 Construct_ss_event_time_and_point_2 ; 00446 00447 typedef CGAL_SS_i::Exceptionless_filtered_construction< typename Unfiltering::Construct_ss_trisegment_2 00448 , typename Exact ::Construct_ss_trisegment_2 00449 , typename Unfiltering::Construct_ss_trisegment_2 00450 , C2E 00451 , C2C 00452 , E2C 00453 , C2C 00454 > 00455 Construct_ss_trisegment_2 ; 00456 } ; 00457 00458 template<class K> 00459 class Straight_skeleton_builder_traits_2 00460 : public Straight_skeleton_builder_traits_2_impl<typename CGAL_SS_i::Is_filtering_kernel<K>::type, K> 00461 { 00462 } ; 00463 00464 CGAL_STRAIGHT_SKELETON_CREATE_FUNCTOR_ADAPTER(Do_ss_event_exist_2); 00465 CGAL_STRAIGHT_SKELETON_CREATE_FUNCTOR_ADAPTER(Compare_ss_event_times_2); 00466 CGAL_STRAIGHT_SKELETON_CREATE_FUNCTOR_ADAPTER(Is_edge_facing_ss_node_2); 00467 CGAL_STRAIGHT_SKELETON_CREATE_FUNCTOR_ADAPTER(Oriented_side_of_event_point_wrt_bisector_2); 00468 CGAL_STRAIGHT_SKELETON_CREATE_FUNCTOR_ADAPTER(Are_ss_events_simultaneous_2); 00469 CGAL_STRAIGHT_SKELETON_CREATE_FUNCTOR_ADAPTER(Are_ss_edges_parallel_2); 00470 CGAL_STRAIGHT_SKELETON_CREATE_FUNCTOR_ADAPTER(Are_ss_edges_collinear_2); 00471 CGAL_STRAIGHT_SKELETON_CREATE_FUNCTOR_ADAPTER(Construct_ss_event_time_and_point_2); 00472 CGAL_STRAIGHT_SKELETON_CREATE_FUNCTOR_ADAPTER(Construct_ss_trisegment_2); 00473 00474 CGAL_END_NAMESPACE 00475 00476 #endif // CGAL_STRAIGHT_SKELETON_BUILDER_TRAITS_2_H // 00477 // EOF //