diff --git a/Alpha_shapes_3/doc/Alpha_shapes_3/CGAL/Alpha_shape_3.h b/Alpha_shapes_3/doc/Alpha_shapes_3/CGAL/Alpha_shape_3.h index e1e14111ed0..9046a58a2eb 100644 --- a/Alpha_shapes_3/doc/Alpha_shapes_3/CGAL/Alpha_shape_3.h +++ b/Alpha_shapes_3/doc/Alpha_shapes_3/CGAL/Alpha_shape_3.h @@ -104,8 +104,11 @@ resorting to exact arithmetic). Access to the interval containing the exact valu `FT::Approximate_nt approx() const` where `FT::Approximate_nt` is `Interval_nt` with `Protected=true`. Access to the exact value is provided through the function `FT::Exact_nt exact() const` where `FT::Exact_nt` depends on the configuration of %CGAL -(it is `Gmpq` if `gmp` is available and `Quotient` otherwise). -An overload for the function `double to_double(FT)` is also available. +(it may be `mpq_class`, `Gmpq`, `Quotient`, etc). +An overload for the function `double to_double(FT)` is also available. Its +precision is controlled through `FT::set_relative_precision_of_to_double()` in +exactly the same way as with `Lazy_exact_nt`, so a call to `to_double` may +trigger an exact evaluation. It must be noted that an object of type `FT` is valid as long as the alpha shapes class that creates it is valid and has not been modified. For convenience, classical comparison operators are provided for the type `FT`. diff --git a/Alpha_shapes_3/include/CGAL/internal/Lazy_alpha_nt_3.h b/Alpha_shapes_3/include/CGAL/internal/Lazy_alpha_nt_3.h index 97005825a79..3a0ffedc88e 100644 --- a/Alpha_shapes_3/include/CGAL/internal/Lazy_alpha_nt_3.h +++ b/Alpha_shapes_3/include/CGAL/internal/Lazy_alpha_nt_3.h @@ -177,8 +177,25 @@ class Lazy_alpha_nt_3{ const Data_vector& data() const{ return input_points;} Data_vector& data(){ return input_points;} + static double & relative_precision_of_to_double_internal() + { + CGAL_STATIC_THREAD_LOCAL_VARIABLE(double, relative_precision_of_to_double, 0.00001); + return relative_precision_of_to_double; + } + public: + static const double & get_relative_precision_of_to_double() + { + return relative_precision_of_to_double_internal(); + } + + static void set_relative_precision_of_to_double(double d) + { + CGAL_assertion((0 < d) & (d < 1)); + relative_precision_of_to_double_internal() = d; + } + typedef NT_exact Exact_nt; typedef NT_approx Approximate_nt; @@ -419,7 +436,17 @@ struct Alpha_nt_selector_3 template double to_double(const internal::Lazy_alpha_nt_3& a) { - return to_double(a.approx()); + double r; + if (fit_in_double(a.approx(), r)) + return r; + + // If it isn't precise enough, + // we trigger the exact computation first, + // which will refine the approximation. + if (!has_smaller_relative_precision(a.approx(), a.get_relative_precision_of_to_double())) + a.exact(); + + return CGAL_NTS to_double(a.approx()); } } //namespace CGAL diff --git a/Number_types/include/CGAL/Lazy_exact_nt.h b/Number_types/include/CGAL/Lazy_exact_nt.h index aa741a97207..d1ffc105ccf 100644 --- a/Number_types/include/CGAL/Lazy_exact_nt.h +++ b/Number_types/include/CGAL/Lazy_exact_nt.h @@ -478,7 +478,7 @@ public: return relative_precision_of_to_double_internal(); } - static void set_relative_precision_of_to_double(const double & d) + static void set_relative_precision_of_to_double(double d) { CGAL_assertion((0 < d) & (d < 1)); relative_precision_of_to_double_internal() = d;