Use exact FT instead of exact Kernel

This commit is contained in:
Laurent Rineau 2022-05-31 18:09:00 +02:00
parent feaf6a4ca2
commit 53b4878a94
4 changed files with 52 additions and 85 deletions

View File

@ -1,25 +0,0 @@
// Copyright (c) 2017
// Utrecht University (The Netherlands),
// ETH Zurich (Switzerland),
// INRIA Sophia-Antipolis (France),
// Max-Planck-Institute Saarbruecken (Germany),
// and Tel-Aviv University (Israel). All rights reserved.
//
// This file is part of CGAL (www.cgal.org)
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Sylvain Pion,
// Mael Rouxel-Labbé
#ifndef CGAL_EXACT_KERNEL_SELECTOR_FWD_H
#define CGAL_EXACT_KERNEL_SELECTOR_FWD_H
namespace CGAL {
template <class CK, class Rep = typename CK::Rep_tag /* Cartesian_tag */>
struct Exact_kernel_selector;
}
#endif // CGAL_EXACT_KERNEL_SELECTOR_FWD_H

View File

@ -27,8 +27,8 @@
#include <CGAL/Intersections_2/Line_2_Line_2.h> #include <CGAL/Intersections_2/Line_2_Line_2.h>
#include <CGAL/Uncertain.h> #include <CGAL/Uncertain.h>
#include <CGAL/Intersection_traits_2.h> #include <CGAL/Intersection_traits_2.h>
#include <CGAL/Cartesian_converter.h> #include <CGAL/NT_converter.h>
#include <CGAL/Exact_kernel_selector_fwd.h> #include <CGAL/Number_types/internal/Exact_type_selector.h>
namespace CGAL { namespace CGAL {
@ -459,30 +459,30 @@ intersection(const typename K::Segment_2 &seg1,
} }
template <class K> template <class K>
boost::optional<typename K::Point_2> typename K::Point_2
exact_intersection_point(const typename K::Point_2& pa, exact_intersection_point(const typename K::Point_2& pa,
const typename K::Point_2& pb, const typename K::Point_2& pb,
const typename K::Point_2& pc, const typename K::Point_2& pc,
const typename K::Point_2& pd, const typename K::Point_2& pd,
const K&) const K&)
{ {
using EK = typename Exact_kernel_selector<K>::Exact_kernel; using FT = typename K::FT;
using EK_Line_2 = typename EK::Line_2; using Exact_FT = typename CGAL::internal::Exact_field_selector<FT>::Type;
using EK_Point_2 = typename EK::Point_2; NT_converter<FT, Exact_FT> to_exact;
Cartesian_converter<K, EK> to_exact; NT_converter<Exact_FT, FT> from_exact;
Cartesian_converter<EK, K> from_exact;
typename EK::Intersect_2 exact_intersect;
const auto exact_intersection =
exact_intersect(EK_Line_2{to_exact(pa), to_exact(pb)},
EK_Line_2{to_exact(pc), to_exact(pd)});
if(!exact_intersection.has_value()) return {};
using boost::get;
if (const auto *p = get<EK_Point_2>(&*exact_intersection)) {
return { from_exact(*p) };
} else {
return {};
}
Exact_FT s1_dx = to_exact(pa.x()) - to_exact(pb.x());
Exact_FT s1_dy = to_exact(pa.y()) - to_exact(pb.y());
Exact_FT s2_dx = to_exact(pd.x()) - to_exact(pc.x());
Exact_FT s2_dy = to_exact(pd.y()) - to_exact(pc.y());
Exact_FT lx = to_exact(pd.x()) - to_exact(pb.x());
Exact_FT ly = to_exact(pd.y()) - to_exact(pb.y());
Exact_FT alpha = (lx*s2_dy-ly*s2_dx)/(s1_dx*s2_dy-s1_dy*s2_dx);
Exact_FT one_minus_alpha = Exact_FT(1) - alpha;
Exact_FT x = alpha * to_exact(pa.x()) + one_minus_alpha * to_exact(pb.x());
Exact_FT y = alpha * to_exact(pa.y()) + one_minus_alpha * to_exact(pb.y());
return { from_exact(x), from_exact(y) };
} }
} // namespace internal } // namespace internal
@ -493,6 +493,4 @@ CGAL_DO_INTERSECT_FUNCTION_SELF(Segment_2, 2)
} //namespace CGAL } //namespace CGAL
#include <CGAL/Exact_kernel_selector.h>
#endif #endif

View File

@ -29,11 +29,9 @@
#include <CGAL/Cartesian_converter.h> #include <CGAL/Cartesian_converter.h>
#include <CGAL/Homogeneous_converter.h> #include <CGAL/Homogeneous_converter.h>
#include <CGAL/Exact_kernel_selector_fwd.h>
namespace CGAL { namespace CGAL {
template <class CK, class Rep /* = typename CK::Rep_tag (Cartesian_tag) */> template <class CK, class Rep = typename CK::Rep_tag /* (Cartesian_tag) */>
struct Exact_kernel_selector struct Exact_kernel_selector
{ {
typedef typename internal::Exact_field_selector<typename CK::RT>::Type Exact_nt; typedef typename internal::Exact_field_selector<typename CK::RT>::Type Exact_nt;

View File

@ -1137,9 +1137,8 @@ intersect(Face_handle f, int i,
intersection_not_in_the_two_triangle(pi)) intersection_not_in_the_two_triangle(pi))
{ {
// now compute the exact intersection point // now compute the exact intersection point
const bool result = pi = almost_exact_intersection(geom_traits(), pa, pb, pc, pd, itag);
almost_exact_intersection(geom_traits(), pa, pb, pc, pd, pi, itag); if (intersection_not_in_the_two_triangle(pi)) {
if (!result || intersection_not_in_the_two_triangle(pi)) {
// If the most-exact intersection point is not in the union of the two // If the most-exact intersection point is not in the union of the two
// triangles, then snap to `pc` or `pd`... // triangles, then snap to `pc` or `pd`...
if(compare_distance(pi, pc, pd) == SMALLER) { if(compare_distance(pi, pc, pd) == SMALLER) {
@ -1865,37 +1864,37 @@ constexpr bool can_construct_almost_exact_intersection(const Gt&, Tag) {
} }
template <typename Gt, typename Tag> template <typename Gt, typename Tag>
bool almost_exact_intersection(const Gt&, typename Gt::Point_2
almost_exact_intersection(const Gt&,
const typename Gt::Point_2&, const typename Gt::Point_2&,
const typename Gt::Point_2&, const typename Gt::Point_2&,
const typename Gt::Point_2&, const typename Gt::Point_2&,
const typename Gt::Point_2&, const typename Gt::Point_2&,
typename Gt::Point_2&,
Tag) Tag)
{ {
CGAL_error_msg("this function should be call only with Exact_predicates_tag"); CGAL_error_msg("this function should be call only with Exact_predicates_tag");
} }
template <typename Gt> template <typename Gt>
bool almost_exact_intersection(const Gt& gt, typename Gt::Point_2
almost_exact_intersection(const Gt& gt,
const typename Gt::Point_2& pa, const typename Gt::Point_2& pa,
const typename Gt::Point_2& pb, const typename Gt::Point_2& pb,
const typename Gt::Point_2& pc, const typename Gt::Point_2& pc,
const typename Gt::Point_2& pd, const typename Gt::Point_2& pd,
typename Gt::Point_2& pi,
Exact_predicates_tag) Exact_predicates_tag)
{ {
Boolean_tag<Can_construct_almost_exact_intersection<Gt>::value> tag; Boolean_tag<Can_construct_almost_exact_intersection<Gt>::value> tag;
return almost_exact_intersection(gt, pa, pb, pc, pd, pi, tag); return almost_exact_intersection(gt, pa, pb, pc, pd, tag);
} }
template <typename Gt> template <typename Gt>
bool almost_exact_intersection(const Gt&, typename Gt::Point_2
almost_exact_intersection(const Gt&,
const typename Gt::Point_2&, const typename Gt::Point_2&,
const typename Gt::Point_2&, const typename Gt::Point_2&,
const typename Gt::Point_2&, const typename Gt::Point_2&,
const typename Gt::Point_2&, const typename Gt::Point_2&,
typename Gt::Point_2&,
Tag_false) Tag_false)
{ {
CGAL_error_msg("this function should be call only with Exact_predicates_tag" CGAL_error_msg("this function should be call only with Exact_predicates_tag"
@ -1903,19 +1902,16 @@ bool almost_exact_intersection(const Gt&,
} }
template <typename Gt> template <typename Gt>
bool almost_exact_intersection(const Gt& gt, typename Gt::Point_2
almost_exact_intersection(const Gt& gt,
const typename Gt::Point_2& pa, const typename Gt::Point_2& pa,
const typename Gt::Point_2& pb, const typename Gt::Point_2& pb,
const typename Gt::Point_2& pc, const typename Gt::Point_2& pc,
const typename Gt::Point_2& pd, const typename Gt::Point_2& pd,
typename Gt::Point_2& pi,
Tag_true /* gt has Construct_exact_intersection_point_2 */) Tag_true /* gt has Construct_exact_intersection_point_2 */)
{ {
auto exact_intersect = gt.construct_exact_intersection_point_2_object(); auto exact_intersect = gt.construct_exact_intersection_point_2_object();
const auto exact_intersection = exact_intersect(pa, pb, pc, pd); return exact_intersect(pa, pb, pc, pd);
if(!exact_intersection.has_value()) return false;
pi = *exact_intersection;
return true;
} }
} //namespace CGAL } //namespace CGAL