From 08db9d7f398783ca9f29c48dd76bdcc5532b19e0 Mon Sep 17 00:00:00 2001 From: Sylvain Pion Date: Wed, 16 May 2001 15:41:34 +0000 Subject: [PATCH] - Handle Angles. --- Packages/Interval_arithmetic/changes.txt | 1 + .../predicates/kernel_ftC2.h | 210 ++++++++++++++ .../predicates/kernel_ftC3.h | 256 ++++++++++++++++++ .../static_infos/predicates/kernel_ftC2.h | 7 + .../static_infos/predicates/kernel_ftC3.h | 7 + .../scripts/filtered_predicates_generator.pl | 3 +- 6 files changed, 483 insertions(+), 1 deletion(-) diff --git a/Packages/Interval_arithmetic/changes.txt b/Packages/Interval_arithmetic/changes.txt index bd74188d329..30173c2a0e9 100644 --- a/Packages/Interval_arithmetic/changes.txt +++ b/Packages/Interval_arithmetic/changes.txt @@ -2,6 +2,7 @@ Changes done to the Interval Arithmetic package. Version 4.88 on 16 May 2001 - Added operator> and operator!= to Interval_base. +- Handle Angles. Version 4.87 on 27 April 2001 - Rename coplanar_side_of_oriented_circle to bounded. diff --git a/Packages/Interval_arithmetic/include/CGAL/Arithmetic_filter/predicates/kernel_ftC2.h b/Packages/Interval_arithmetic/include/CGAL/Arithmetic_filter/predicates/kernel_ftC2.h index 452c19ec897..63c92b64b92 100644 --- a/Packages/Interval_arithmetic/include/CGAL/Arithmetic_filter/predicates/kernel_ftC2.h +++ b/Packages/Interval_arithmetic/include/CGAL/Arithmetic_filter/predicates/kernel_ftC2.h @@ -2782,6 +2782,216 @@ orientationC2( #endif // CGAL_IA_NEW_FILTERS +#ifndef CGAL_CFG_MATCHING_BUG_2 +template < class CGAL_IA_CT, class CGAL_IA_ET, bool CGAL_IA_PROTECTED, + class CGAL_IA_CACHE > +#else +static +#endif +/* inline */ +Angle +angleC2( + const Filtered_exact &px, + const Filtered_exact &py, + const Filtered_exact &qx, + const Filtered_exact &qy, + const Filtered_exact &rx, + const Filtered_exact &ry) +{ + try + { + Protect_FPU_rounding Protection; + return angleC2( + px.interval(), + py.interval(), + qx.interval(), + qy.interval(), + rx.interval(), + ry.interval()); + } + catch (Interval_nt_advanced::unsafe_comparison) + { + Protect_FPU_rounding Protection(CGAL_FE_TONEAREST); + return angleC2( + px.exact(), + py.exact(), + qx.exact(), + qy.exact(), + rx.exact(), + ry.exact()); + } +} + +#ifdef CGAL_IA_NEW_FILTERS + +struct Static_Filtered_angleC2_6 +{ + static double _bound; + static double _epsilon_0; + static unsigned number_of_failures; // ? + static unsigned number_of_updates; + + static Angle update_epsilon( + const Static_filter_error &px, + const Static_filter_error &py, + const Static_filter_error &qx, + const Static_filter_error &qy, + const Static_filter_error &rx, + const Static_filter_error &ry, + double & epsilon_0) + { + typedef Static_filter_error FT; + + return (Angle) CGAL_NTS Static_Filtered_sign_1::update_epsilon((px-qx)*(rx-qx)+(py-qy)*(ry-qy), + epsilon_0); + } + + // Call this function from the outside to update the context. + static void new_bound (const double b) // , const double error = 0) + { + _bound = b; + number_of_updates++; + // recompute the epsilons: "just" call it over Static_filter_error. + // That's the tricky part that might not work for everything. + (void) update_epsilon(b,b,b,b,b,b,_epsilon_0); + // TODO: We should verify that all epsilons have really been updated. + } + + static Angle epsilon_variant( + const Restricted_double &px, + const Restricted_double &py, + const Restricted_double &qx, + const Restricted_double &qy, + const Restricted_double &rx, + const Restricted_double &ry, + const double & epsilon_0) + { + typedef Restricted_double FT; + + return (Angle) CGAL_NTS Static_Filtered_sign_1::epsilon_variant((px-qx)*(rx-qx)+(py-qy)*(ry-qy), + epsilon_0); + } +}; + +#ifndef CGAL_CFG_MATCHING_BUG_2 +template < class CGAL_IA_CT, class CGAL_IA_ET, class CGAL_IA_CACHE > +#else +static +#endif +/* inline */ +Angle +angleC2( + const Filtered_exact &px, + const Filtered_exact &py, + const Filtered_exact &qx, + const Filtered_exact &qy, + const Filtered_exact &rx, + const Filtered_exact &ry) +{ +// bool re_adjusted = false; + const double SAF_bound = Static_Filtered_angleC2_6::_bound; + + // Check the bounds. All arguments must be <= SAF_bound. + if ( + fabs(px.to_double()) > SAF_bound || + fabs(py.to_double()) > SAF_bound || + fabs(qx.to_double()) > SAF_bound || + fabs(qy.to_double()) > SAF_bound || + fabs(rx.to_double()) > SAF_bound || + fabs(ry.to_double()) > SAF_bound) + { +// re_adjust: + // Compute the new bound. + double NEW_bound = 0.0; + NEW_bound = max(NEW_bound, fabs(px.to_double())); + NEW_bound = max(NEW_bound, fabs(py.to_double())); + NEW_bound = max(NEW_bound, fabs(qx.to_double())); + NEW_bound = max(NEW_bound, fabs(qy.to_double())); + NEW_bound = max(NEW_bound, fabs(rx.to_double())); + NEW_bound = max(NEW_bound, fabs(ry.to_double())); + // Re-adjust the context. + Static_Filtered_angleC2_6::new_bound(NEW_bound); + } + + try + { + return Static_Filtered_angleC2_6::epsilon_variant( + px.dbl(), + py.dbl(), + qx.dbl(), + qy.dbl(), + rx.dbl(), + ry.dbl(), + Static_Filtered_angleC2_6::_epsilon_0); + } + catch (...) + { + // if (!re_adjusted) { // It failed, we re-adjust once. + // re_adjusted = true; + // goto re_adjust; + // } + Static_Filtered_angleC2_6::number_of_failures++; + return angleC2( + px.exact(), + py.exact(), + qx.exact(), + qy.exact(), + rx.exact(), + ry.exact()); + } +} + +#ifndef CGAL_CFG_MATCHING_BUG_2 +template < class CGAL_IA_CT, class CGAL_IA_ET, class CGAL_IA_CACHE > +#else +static +#endif +/* inline */ +Angle +angleC2( + const Filtered_exact &px, + const Filtered_exact &py, + const Filtered_exact &qx, + const Filtered_exact &qy, + const Filtered_exact &rx, + const Filtered_exact &ry) +{ + CGAL_assertion_code( + const double SAF_bound = Static_Filtered_angleC2_6::_bound; ) + CGAL_assertion(!( + fabs(px.to_double()) > SAF_bound || + fabs(py.to_double()) > SAF_bound || + fabs(qx.to_double()) > SAF_bound || + fabs(qy.to_double()) > SAF_bound || + fabs(rx.to_double()) > SAF_bound || + fabs(ry.to_double()) > SAF_bound)); + + try + { + return Static_Filtered_angleC2_6::epsilon_variant( + px.dbl(), + py.dbl(), + qx.dbl(), + qy.dbl(), + rx.dbl(), + ry.dbl(), + Static_Filtered_angleC2_6::_epsilon_0); + } + catch (...) + { + Static_Filtered_angleC2_6::number_of_failures++; + return angleC2( + px.exact(), + py.exact(), + qx.exact(), + qy.exact(), + rx.exact(), + ry.exact()); + } +} + +#endif // CGAL_IA_NEW_FILTERS + #ifndef CGAL_CFG_MATCHING_BUG_2 template < class CGAL_IA_CT, class CGAL_IA_ET, bool CGAL_IA_PROTECTED, class CGAL_IA_CACHE > diff --git a/Packages/Interval_arithmetic/include/CGAL/Arithmetic_filter/predicates/kernel_ftC3.h b/Packages/Interval_arithmetic/include/CGAL/Arithmetic_filter/predicates/kernel_ftC3.h index 3fefdacba41..99073bc9f73 100644 --- a/Packages/Interval_arithmetic/include/CGAL/Arithmetic_filter/predicates/kernel_ftC3.h +++ b/Packages/Interval_arithmetic/include/CGAL/Arithmetic_filter/predicates/kernel_ftC3.h @@ -1058,6 +1058,262 @@ orientationC3( #endif // CGAL_IA_NEW_FILTERS +#ifndef CGAL_CFG_MATCHING_BUG_2 +template < class CGAL_IA_CT, class CGAL_IA_ET, bool CGAL_IA_PROTECTED, + class CGAL_IA_CACHE > +#else +static +#endif +/* inline */ +Angle +angleC3( + const Filtered_exact &px, + const Filtered_exact &py, + const Filtered_exact &pz, + const Filtered_exact &qx, + const Filtered_exact &qy, + const Filtered_exact &qz, + const Filtered_exact &rx, + const Filtered_exact &ry, + const Filtered_exact &rz) +{ + try + { + Protect_FPU_rounding Protection; + return angleC3( + px.interval(), + py.interval(), + pz.interval(), + qx.interval(), + qy.interval(), + qz.interval(), + rx.interval(), + ry.interval(), + rz.interval()); + } + catch (Interval_nt_advanced::unsafe_comparison) + { + Protect_FPU_rounding Protection(CGAL_FE_TONEAREST); + return angleC3( + px.exact(), + py.exact(), + pz.exact(), + qx.exact(), + qy.exact(), + qz.exact(), + rx.exact(), + ry.exact(), + rz.exact()); + } +} + +#ifdef CGAL_IA_NEW_FILTERS + +struct Static_Filtered_angleC3_9 +{ + static double _bound; + static double _epsilon_0; + static unsigned number_of_failures; // ? + static unsigned number_of_updates; + + static Angle update_epsilon( + const Static_filter_error &px, + const Static_filter_error &py, + const Static_filter_error &pz, + const Static_filter_error &qx, + const Static_filter_error &qy, + const Static_filter_error &qz, + const Static_filter_error &rx, + const Static_filter_error &ry, + const Static_filter_error &rz, + double & epsilon_0) + { + typedef Static_filter_error FT; + + return (Angle) CGAL_NTS Static_Filtered_sign_1::update_epsilon((px-qx)*(rx-qx)+ + (py-qy)*(ry-qy)+ + (pz-qz)*(rz-qz), + epsilon_0); + } + + // Call this function from the outside to update the context. + static void new_bound (const double b) // , const double error = 0) + { + _bound = b; + number_of_updates++; + // recompute the epsilons: "just" call it over Static_filter_error. + // That's the tricky part that might not work for everything. + (void) update_epsilon(b,b,b,b,b,b,b,b,b,_epsilon_0); + // TODO: We should verify that all epsilons have really been updated. + } + + static Angle epsilon_variant( + const Restricted_double &px, + const Restricted_double &py, + const Restricted_double &pz, + const Restricted_double &qx, + const Restricted_double &qy, + const Restricted_double &qz, + const Restricted_double &rx, + const Restricted_double &ry, + const Restricted_double &rz, + const double & epsilon_0) + { + typedef Restricted_double FT; + + return (Angle) CGAL_NTS Static_Filtered_sign_1::epsilon_variant((px-qx)*(rx-qx)+ + (py-qy)*(ry-qy)+ + (pz-qz)*(rz-qz), + epsilon_0); + } +}; + +#ifndef CGAL_CFG_MATCHING_BUG_2 +template < class CGAL_IA_CT, class CGAL_IA_ET, class CGAL_IA_CACHE > +#else +static +#endif +/* inline */ +Angle +angleC3( + const Filtered_exact &px, + const Filtered_exact &py, + const Filtered_exact &pz, + const Filtered_exact &qx, + const Filtered_exact &qy, + const Filtered_exact &qz, + const Filtered_exact &rx, + const Filtered_exact &ry, + const Filtered_exact &rz) +{ +// bool re_adjusted = false; + const double SAF_bound = Static_Filtered_angleC3_9::_bound; + + // Check the bounds. All arguments must be <= SAF_bound. + if ( + fabs(px.to_double()) > SAF_bound || + fabs(py.to_double()) > SAF_bound || + fabs(pz.to_double()) > SAF_bound || + fabs(qx.to_double()) > SAF_bound || + fabs(qy.to_double()) > SAF_bound || + fabs(qz.to_double()) > SAF_bound || + fabs(rx.to_double()) > SAF_bound || + fabs(ry.to_double()) > SAF_bound || + fabs(rz.to_double()) > SAF_bound) + { +// re_adjust: + // Compute the new bound. + double NEW_bound = 0.0; + NEW_bound = max(NEW_bound, fabs(px.to_double())); + NEW_bound = max(NEW_bound, fabs(py.to_double())); + NEW_bound = max(NEW_bound, fabs(pz.to_double())); + NEW_bound = max(NEW_bound, fabs(qx.to_double())); + NEW_bound = max(NEW_bound, fabs(qy.to_double())); + NEW_bound = max(NEW_bound, fabs(qz.to_double())); + NEW_bound = max(NEW_bound, fabs(rx.to_double())); + NEW_bound = max(NEW_bound, fabs(ry.to_double())); + NEW_bound = max(NEW_bound, fabs(rz.to_double())); + // Re-adjust the context. + Static_Filtered_angleC3_9::new_bound(NEW_bound); + } + + try + { + return Static_Filtered_angleC3_9::epsilon_variant( + px.dbl(), + py.dbl(), + pz.dbl(), + qx.dbl(), + qy.dbl(), + qz.dbl(), + rx.dbl(), + ry.dbl(), + rz.dbl(), + Static_Filtered_angleC3_9::_epsilon_0); + } + catch (...) + { + // if (!re_adjusted) { // It failed, we re-adjust once. + // re_adjusted = true; + // goto re_adjust; + // } + Static_Filtered_angleC3_9::number_of_failures++; + return angleC3( + px.exact(), + py.exact(), + pz.exact(), + qx.exact(), + qy.exact(), + qz.exact(), + rx.exact(), + ry.exact(), + rz.exact()); + } +} + +#ifndef CGAL_CFG_MATCHING_BUG_2 +template < class CGAL_IA_CT, class CGAL_IA_ET, class CGAL_IA_CACHE > +#else +static +#endif +/* inline */ +Angle +angleC3( + const Filtered_exact &px, + const Filtered_exact &py, + const Filtered_exact &pz, + const Filtered_exact &qx, + const Filtered_exact &qy, + const Filtered_exact &qz, + const Filtered_exact &rx, + const Filtered_exact &ry, + const Filtered_exact &rz) +{ + CGAL_assertion_code( + const double SAF_bound = Static_Filtered_angleC3_9::_bound; ) + CGAL_assertion(!( + fabs(px.to_double()) > SAF_bound || + fabs(py.to_double()) > SAF_bound || + fabs(pz.to_double()) > SAF_bound || + fabs(qx.to_double()) > SAF_bound || + fabs(qy.to_double()) > SAF_bound || + fabs(qz.to_double()) > SAF_bound || + fabs(rx.to_double()) > SAF_bound || + fabs(ry.to_double()) > SAF_bound || + fabs(rz.to_double()) > SAF_bound)); + + try + { + return Static_Filtered_angleC3_9::epsilon_variant( + px.dbl(), + py.dbl(), + pz.dbl(), + qx.dbl(), + qy.dbl(), + qz.dbl(), + rx.dbl(), + ry.dbl(), + rz.dbl(), + Static_Filtered_angleC3_9::_epsilon_0); + } + catch (...) + { + Static_Filtered_angleC3_9::number_of_failures++; + return angleC3( + px.exact(), + py.exact(), + pz.exact(), + qx.exact(), + qy.exact(), + qz.exact(), + rx.exact(), + ry.exact(), + rz.exact()); + } +} + +#endif // CGAL_IA_NEW_FILTERS + #ifndef CGAL_CFG_MATCHING_BUG_2 template < class CGAL_IA_CT, class CGAL_IA_ET, bool CGAL_IA_PROTECTED, class CGAL_IA_CACHE > diff --git a/Packages/Interval_arithmetic/include/CGAL/Arithmetic_filter/static_infos/predicates/kernel_ftC2.h b/Packages/Interval_arithmetic/include/CGAL/Arithmetic_filter/static_infos/predicates/kernel_ftC2.h index 7f6abb648f7..e2ee190450a 100644 --- a/Packages/Interval_arithmetic/include/CGAL/Arithmetic_filter/static_infos/predicates/kernel_ftC2.h +++ b/Packages/Interval_arithmetic/include/CGAL/Arithmetic_filter/static_infos/predicates/kernel_ftC2.h @@ -125,6 +125,13 @@ unsigned Static_Filtered_orientationC2_6::number_of_updates = 0; unsigned Static_Filtered_orientationC2_6::number_of_failures = 0; +double Static_Filtered_angleC2_6::_epsilon_0; +double Static_Filtered_angleC2_6::_bound = -1.0; + +unsigned Static_Filtered_angleC2_6::number_of_updates = 0; + +unsigned Static_Filtered_angleC2_6::number_of_failures = 0; + double Static_Filtered_side_of_oriented_circleC2_8::_epsilon_0; double Static_Filtered_side_of_oriented_circleC2_8::_bound = -1.0; diff --git a/Packages/Interval_arithmetic/include/CGAL/Arithmetic_filter/static_infos/predicates/kernel_ftC3.h b/Packages/Interval_arithmetic/include/CGAL/Arithmetic_filter/static_infos/predicates/kernel_ftC3.h index cc71e69e6f9..db80cb41042 100644 --- a/Packages/Interval_arithmetic/include/CGAL/Arithmetic_filter/static_infos/predicates/kernel_ftC3.h +++ b/Packages/Interval_arithmetic/include/CGAL/Arithmetic_filter/static_infos/predicates/kernel_ftC3.h @@ -58,6 +58,13 @@ unsigned Static_Filtered_orientationC3_12::number_of_updates = 0; unsigned Static_Filtered_orientationC3_12::number_of_failures = 0; +double Static_Filtered_angleC3_9::_epsilon_0; +double Static_Filtered_angleC3_9::_bound = -1.0; + +unsigned Static_Filtered_angleC3_9::number_of_updates = 0; + +unsigned Static_Filtered_angleC3_9::number_of_failures = 0; + double Static_Filtered_coplanar_side_of_bounded_circleC3_12::_epsilon_0; double Static_Filtered_coplanar_side_of_bounded_circleC3_12::_bound = -1.0; diff --git a/Packages/Interval_arithmetic/scripts/filtered_predicates_generator.pl b/Packages/Interval_arithmetic/scripts/filtered_predicates_generator.pl index 48be1f0df2c..7a2a3579efe 100755 --- a/Packages/Interval_arithmetic/scripts/filtered_predicates_generator.pl +++ b/Packages/Interval_arithmetic/scripts/filtered_predicates_generator.pl @@ -434,7 +434,8 @@ sub parse_dependancy_files { # Main program sub main { - for ("Sign","Comparison_result","Orientation","Oriented_side","Bounded_side") + for ("Sign","Comparison_result","Orientation","Oriented_side","Bounded_side", + "Angle") { $known_ret_types{$_}=1; $known_ret_types{"CGAL::$_"}=1;