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 };
|
||||
typedef Boolean_tag<Has_filtered_predicates> Has_filtered_predicates_tag;
|
||||
|
||||
typedef Tag_true Can_construct_exact_intersection_point_2;
|
||||
|
||||
template < typename Kernel2 >
|
||||
struct Base {
|
||||
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/Uncertain.h>
|
||||
#include <CGAL/Intersection_traits_2.h>
|
||||
#include <CGAL/Cartesian_converter.h>
|
||||
#include <CGAL/Exact_kernel_selector_fwd.h>
|
||||
|
||||
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 Intersections
|
||||
|
||||
|
|
@ -464,4 +493,6 @@ CGAL_DO_INTERSECT_FUNCTION_SELF(Segment_2, 2)
|
|||
|
||||
} //namespace CGAL
|
||||
|
||||
#include <CGAL/Exact_kernel_selector.h>
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -29,9 +29,11 @@
|
|||
#include <CGAL/Cartesian_converter.h>
|
||||
#include <CGAL/Homogeneous_converter.h>
|
||||
|
||||
#include <CGAL/Exact_kernel_selector_fwd.h>
|
||||
|
||||
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
|
||||
{
|
||||
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()); }
|
||||
};
|
||||
|
||||
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>
|
||||
class Intersect_3
|
||||
{
|
||||
|
|
|
|||
|
|
@ -302,6 +302,8 @@ CGAL_Kernel_cons(Construct_circumcenter_3,
|
|||
construct_circumcenter_3_object)
|
||||
CGAL_Kernel_cons(Construct_weighted_circumcenter_3,
|
||||
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,
|
||||
compute_power_product_2_object)
|
||||
CGAL_Kernel_cons(Compute_power_product_3,
|
||||
|
|
|
|||
|
|
@ -28,10 +28,11 @@
|
|||
#include <CGAL/Default.h>
|
||||
#include <CGAL/intersections.h>
|
||||
#include <CGAL/squared_distance_2.h>
|
||||
#include <CGAL/Exact_rational.h>
|
||||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/tags.h>
|
||||
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/has_xxx.hpp>
|
||||
#include <boost/iterator/filter_iterator.hpp>
|
||||
|
||||
#include <boost/utility/result_of.hpp>
|
||||
|
|
@ -1132,25 +1133,13 @@ intersect(Face_handle f, int i,
|
|||
}
|
||||
}
|
||||
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
|
||||
using EK = Simple_cartesian<Exact_rational>;
|
||||
using EK_Line_2 = EK::Line_2;
|
||||
using EK_Point_2 = EK::Point_2;
|
||||
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)) {
|
||||
const bool result =
|
||||
almost_exact_intersection(geom_traits(), pa, pb, pc, pd, pi, itag);
|
||||
if (!result || intersection_not_in_the_two_triangle(pi)) {
|
||||
// If the most-exact intersection point is not in the union of the two
|
||||
// triangles, then snap to `pc` or `pd`...
|
||||
if(compare_distance(pi, pc, pd) == SMALLER) {
|
||||
|
|
@ -1853,6 +1842,82 @@ limit_intersection(const Gt& gt,
|
|||
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
|
||||
|
||||
#include <CGAL/enable_warnings.h>
|
||||
|
|
|
|||
Loading…
Reference in New Issue