mirror of https://github.com/CGAL/cgal
Add Kernel::Construct_exact_intersection_point_2
This commit is contained in:
parent
e60a6327be
commit
feaf6a4ca2
|
|
@ -61,6 +61,8 @@ struct Filtered_kernel_base
|
||||||
enum { Has_filtered_predicates = true };
|
enum { Has_filtered_predicates = true };
|
||||||
typedef Boolean_tag<Has_filtered_predicates> Has_filtered_predicates_tag;
|
typedef Boolean_tag<Has_filtered_predicates> Has_filtered_predicates_tag;
|
||||||
|
|
||||||
|
typedef Tag_true Can_construct_exact_intersection_point_2;
|
||||||
|
|
||||||
template < typename Kernel2 >
|
template < typename Kernel2 >
|
||||||
struct Base {
|
struct Base {
|
||||||
typedef typename CK::template Base<Kernel2> CK2;
|
typedef typename CK::template Base<Kernel2> CK2;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
// 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
|
||||||
|
|
@ -27,6 +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/Exact_kernel_selector_fwd.h>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
|
|
@ -456,6 +458,33 @@ intersection(const typename K::Segment_2 &seg1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
boost::optional<typename K::Point_2>
|
||||||
|
exact_intersection_point(const typename K::Point_2& pa,
|
||||||
|
const typename K::Point_2& pb,
|
||||||
|
const typename K::Point_2& pc,
|
||||||
|
const typename K::Point_2& pd,
|
||||||
|
const K&)
|
||||||
|
{
|
||||||
|
using EK = typename Exact_kernel_selector<K>::Exact_kernel;
|
||||||
|
using EK_Line_2 = typename EK::Line_2;
|
||||||
|
using EK_Point_2 = typename EK::Point_2;
|
||||||
|
Cartesian_converter<K, EK> to_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 {};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace Intersections
|
} // namespace Intersections
|
||||||
|
|
||||||
|
|
@ -464,4 +493,6 @@ CGAL_DO_INTERSECT_FUNCTION_SELF(Segment_2, 2)
|
||||||
|
|
||||||
} //namespace CGAL
|
} //namespace CGAL
|
||||||
|
|
||||||
|
#include <CGAL/Exact_kernel_selector.h>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,11 @@
|
||||||
#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;
|
||||||
|
|
|
||||||
|
|
@ -3553,6 +3553,17 @@ namespace CommonKernelFunctors {
|
||||||
{ return Intersections::internal::intersection(t1, t2, K()); }
|
{ return Intersections::internal::intersection(t1, t2, K()); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename K>
|
||||||
|
class Construct_exact_intersection_point_2
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
template <class... T>
|
||||||
|
decltype(auto)
|
||||||
|
operator()(const T&... t) const
|
||||||
|
{ return Intersections::internal::exact_intersection_point(t..., K()); }
|
||||||
|
};
|
||||||
|
|
||||||
template <typename K>
|
template <typename K>
|
||||||
class Intersect_3
|
class Intersect_3
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -302,6 +302,8 @@ CGAL_Kernel_cons(Construct_circumcenter_3,
|
||||||
construct_circumcenter_3_object)
|
construct_circumcenter_3_object)
|
||||||
CGAL_Kernel_cons(Construct_weighted_circumcenter_3,
|
CGAL_Kernel_cons(Construct_weighted_circumcenter_3,
|
||||||
construct_weighted_circumcenter_3_object)
|
construct_weighted_circumcenter_3_object)
|
||||||
|
CGAL_Kernel_cons(Construct_exact_intersection_point_2,
|
||||||
|
construct_exact_intersection_point_2_object)
|
||||||
CGAL_Kernel_cons(Compute_power_product_2,
|
CGAL_Kernel_cons(Compute_power_product_2,
|
||||||
compute_power_product_2_object)
|
compute_power_product_2_object)
|
||||||
CGAL_Kernel_cons(Compute_power_product_3,
|
CGAL_Kernel_cons(Compute_power_product_3,
|
||||||
|
|
|
||||||
|
|
@ -28,10 +28,11 @@
|
||||||
#include <CGAL/Default.h>
|
#include <CGAL/Default.h>
|
||||||
#include <CGAL/intersections.h>
|
#include <CGAL/intersections.h>
|
||||||
#include <CGAL/squared_distance_2.h>
|
#include <CGAL/squared_distance_2.h>
|
||||||
#include <CGAL/Exact_rational.h>
|
#include <CGAL/tags.h>
|
||||||
#include <CGAL/Simple_cartesian.h>
|
|
||||||
|
|
||||||
#include <boost/mpl/if.hpp>
|
#include <boost/mpl/if.hpp>
|
||||||
|
#include <boost/mpl/has_xxx.hpp>
|
||||||
#include <boost/iterator/filter_iterator.hpp>
|
#include <boost/iterator/filter_iterator.hpp>
|
||||||
|
|
||||||
#include <boost/utility/result_of.hpp>
|
#include <boost/utility/result_of.hpp>
|
||||||
|
|
@ -1132,25 +1133,13 @@ intersect(Face_handle f, int i,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{ //intersection computed
|
else{ //intersection computed
|
||||||
if(intersection_not_in_the_two_triangle(pi)) {
|
if(can_construct_almost_exact_intersection(geom_traits(), itag) &&
|
||||||
|
intersection_not_in_the_two_triangle(pi))
|
||||||
|
{
|
||||||
// now compute the exact intersection point
|
// now compute the exact intersection point
|
||||||
using EK = Simple_cartesian<Exact_rational>;
|
const bool result =
|
||||||
using EK_Line_2 = EK::Line_2;
|
almost_exact_intersection(geom_traits(), pa, pb, pc, pd, pi, itag);
|
||||||
using EK_Point_2 = EK::Point_2;
|
if (!result || intersection_not_in_the_two_triangle(pi)) {
|
||||||
Cartesian_converter<Gt, EK> to_exact;
|
|
||||||
Cartesian_converter<EK, Gt> from_exact;
|
|
||||||
EK::Intersect_2 exact_intersect;
|
|
||||||
auto exact_intersection =
|
|
||||||
exact_intersect(EK_Line_2{to_exact(pa), to_exact(pb)},
|
|
||||||
EK_Line_2{to_exact(pc), to_exact(pd)});
|
|
||||||
CGAL_assertion(exact_intersection.has_value());
|
|
||||||
using boost::get;
|
|
||||||
if (const auto *p = get<EK_Point_2>(&*exact_intersection)) {
|
|
||||||
pi = from_exact(*p);
|
|
||||||
} else {
|
|
||||||
CGAL_error();
|
|
||||||
}
|
|
||||||
if(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) {
|
||||||
|
|
@ -1831,11 +1820,11 @@ limit_intersection(const Gt& ,
|
||||||
template<class Gt>
|
template<class Gt>
|
||||||
int
|
int
|
||||||
limit_intersection(const Gt& gt,
|
limit_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,
|
||||||
Exact_predicates_tag)
|
Exact_predicates_tag)
|
||||||
{
|
{
|
||||||
typename Gt::Construct_line_2 line = gt.construct_line_2_object();
|
typename Gt::Construct_line_2 line = gt.construct_line_2_object();
|
||||||
typename Gt::Compute_squared_distance_2
|
typename Gt::Compute_squared_distance_2
|
||||||
|
|
@ -1853,6 +1842,82 @@ limit_intersection(const Gt& gt,
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_MPL_HAS_XXX_TRAIT_DEF(Can_construct_exact_intersection_point_2)
|
||||||
|
|
||||||
|
template <typename Gt,
|
||||||
|
bool = has_Can_construct_exact_intersection_point_2<Gt>::value>
|
||||||
|
struct Can_construct_almost_exact_intersection
|
||||||
|
: public CGAL::Boolean_tag<
|
||||||
|
Gt::Can_construct_exact_intersection_point_2::value> {};
|
||||||
|
|
||||||
|
template <typename Gt>
|
||||||
|
struct Can_construct_almost_exact_intersection<Gt, false>
|
||||||
|
: public CGAL::Tag_false {};
|
||||||
|
|
||||||
|
template <typename Gt>
|
||||||
|
constexpr bool can_construct_almost_exact_intersection(const Gt&, Exact_predicates_tag) {
|
||||||
|
return Can_construct_almost_exact_intersection<Gt>::value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Gt, typename Tag>
|
||||||
|
constexpr bool can_construct_almost_exact_intersection(const Gt&, Tag) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Gt, typename Tag>
|
||||||
|
bool 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&,
|
||||||
|
typename Gt::Point_2&,
|
||||||
|
Tag)
|
||||||
|
{
|
||||||
|
CGAL_error_msg("this function should be call only with Exact_predicates_tag");
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Gt>
|
||||||
|
bool almost_exact_intersection(const Gt& gt,
|
||||||
|
const typename Gt::Point_2& pa,
|
||||||
|
const typename Gt::Point_2& pb,
|
||||||
|
const typename Gt::Point_2& pc,
|
||||||
|
const typename Gt::Point_2& pd,
|
||||||
|
typename Gt::Point_2& pi,
|
||||||
|
Exact_predicates_tag)
|
||||||
|
{
|
||||||
|
Boolean_tag<Can_construct_almost_exact_intersection<Gt>::value> tag;
|
||||||
|
return almost_exact_intersection(gt, pa, pb, pc, pd, pi, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Gt>
|
||||||
|
bool 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&,
|
||||||
|
typename Gt::Point_2&,
|
||||||
|
Tag_false)
|
||||||
|
{
|
||||||
|
CGAL_error_msg("this function should be call only with Exact_predicates_tag"
|
||||||
|
" and with an appropriate traits class");
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Gt>
|
||||||
|
bool almost_exact_intersection(const Gt& gt,
|
||||||
|
const typename Gt::Point_2& pa,
|
||||||
|
const typename Gt::Point_2& pb,
|
||||||
|
const typename Gt::Point_2& pc,
|
||||||
|
const typename Gt::Point_2& pd,
|
||||||
|
typename Gt::Point_2& pi,
|
||||||
|
Tag_true /* gt has Construct_exact_intersection_point_2 */)
|
||||||
|
{
|
||||||
|
auto exact_intersect = gt.construct_exact_intersection_point_2_object();
|
||||||
|
const auto exact_intersection = exact_intersect(pa, pb, pc, pd);
|
||||||
|
if(!exact_intersection.has_value()) return false;
|
||||||
|
pi = *exact_intersection;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} //namespace CGAL
|
} //namespace CGAL
|
||||||
|
|
||||||
#include <CGAL/enable_warnings.h>
|
#include <CGAL/enable_warnings.h>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue