Suppressed using Polyline with do_intersect() and fixed the do-intersect oberlay sweep-line visitor

This commit is contained in:
Efi Fogel 2025-08-25 19:10:19 +03:00
parent 35721db0b9
commit 0f528545c7
4 changed files with 122 additions and 69 deletions

View File

@ -115,19 +115,19 @@ bool do_intersect_overlay(const Arrangement_on_surface_2<GeometryTraitsA_2, Topo
// directed from right to left.
typename Arr_a::Halfedge_const_handle invalid_he1;
typename Arr_b::Halfedge_const_handle invalid_he2;
std::vector<Ovl_x_monotone_curve_2> xcvs_vec(arr1.number_of_edges() + arr2.number_of_edges());
std::vector<Ovl_x_monotone_curve_2> xcvs(arr1.number_of_edges() + arr2.number_of_edges());
std::size_t i = 0;
for (auto eit1 = arr1.edges_begin(); eit1 != arr1.edges_end(); ++eit1, ++i) {
typename Arr_a::Halfedge_const_handle he1 = eit1;
if (he1->direction() != ARR_RIGHT_TO_LEFT) he1 = he1->twin();
xcvs_vec[i] = Ovl_x_monotone_curve_2(eit1->curve(), he1, invalid_he2);
xcvs[i] = Ovl_x_monotone_curve_2(eit1->curve(), he1, invalid_he2);
}
for (auto eit2 = arr2.edges_begin(); eit2 != arr2.edges_end(); ++eit2, ++i) {
typename Arr_b::Halfedge_const_handle he2 = eit2;
if (he2->direction() != ARR_RIGHT_TO_LEFT) he2 = he2->twin();
xcvs_vec[i] = Ovl_x_monotone_curve_2(eit2->curve(), invalid_he1, he2);
xcvs[i] = Ovl_x_monotone_curve_2(eit2->curve(), invalid_he1, he2);
}
// Obtain an extended traits-class object and define the sweep-line visitor.
@ -155,12 +155,18 @@ bool do_intersect_overlay(const Arrangement_on_surface_2<GeometryTraitsA_2, Topo
((arr1.number_of_isolated_vertices() == 0) && (arr2.number_of_isolated_vertices() == 0))) {
// Clear the result arrangement and perform the sweep to construct it.
arr.clear();
if (std::is_same<typename Agt2::Bottom_side_category, Arr_contracted_side_tag>::value)
surface_sweep.sweep(xcvs_vec.begin(), xcvs_vec.end());
else
surface_sweep.indexed_sweep(xcvs_vec, Indexed_sweep_accessor<Arr_a, Arr_b, Ovl_x_monotone_curve_2>(arr1, arr2));
xcvs_vec.clear();
return false;
if (std::is_same<typename Agt2::Bottom_side_category, Arr_contracted_side_tag>::value) {
surface_sweep.sweep(xcvs.begin(), xcvs.end());
xcvs.clear();
return visitor.found_intersection();
}
{
for (const auto& xcv : xcvs) std::cout << xcv << std::endl;
std::cout << std::endl;
}
surface_sweep.indexed_sweep(xcvs, Indexed_sweep_accessor<Arr_a, Arr_b, Ovl_x_monotone_curve_2>(arr1, arr2));
xcvs.clear();
return visitor.found_intersection();
}
// Prepare a vector of extended points that represent all isolated vertices
@ -186,14 +192,17 @@ bool do_intersect_overlay(const Arrangement_on_surface_2<GeometryTraitsA_2, Topo
// Clear the result arrangement and perform the sweep to construct it.
arr.clear();
if (std::is_same<typename Agt2::Bottom_side_category, Arr_contracted_side_tag>::value)
surface_sweep.sweep(xcvs_vec.begin(), xcvs_vec.end(), pts_vec.begin(), pts_vec.end());
else
surface_sweep.indexed_sweep(xcvs_vec, Indexed_sweep_accessor<Arr_a, Arr_b, Ovl_x_monotone_curve_2>(arr1, arr2),
pts_vec.begin(), pts_vec.end());
xcvs_vec.clear();
if (std::is_same<typename Agt2::Bottom_side_category, Arr_contracted_side_tag>::value) {
surface_sweep.sweep(xcvs.begin(), xcvs.end(), pts_vec.begin(), pts_vec.end());
xcvs.clear();
pts_vec.clear();
return visitor.found_intersection();
}
surface_sweep.indexed_sweep(xcvs, Indexed_sweep_accessor<Arr_a, Arr_b, Ovl_x_monotone_curve_2>(arr1, arr2),
pts_vec.begin(), pts_vec.end());
xcvs.clear();
pts_vec.clear();
return false;
return visitor.found_intersection();
}
/*! Compute the (simple) overlay of two input arrangements.

View File

@ -49,21 +49,67 @@ private:
using Visitor = typename Default::Get<Visitor_, Self>::type;
using Base = Arr_overlay_ss_visitor<Overlay_helper, Overlay_traits, Visitor>;
protected:
bool m_found_x;
public:
using Arrangement_red_2 = typename Base::Arrangement_red_2;
using Arrangement_blue_2 = typename Base::Arrangement_blue_2;
using Arrangement_2 = typename Base::Arrangement_2;
using Event = typename Base::Event;
using Subcurve = typename Base::Subcurve;
using Status_line_iterator = typename Base::Status_line_iterator;
using X_monotone_curve_2 = typename Base::X_monotone_curve_2;
using Point_2 = typename Base::Point_2;
/*! Constructor */
Arr_do_intersect_overlay_ss_visitor(const Arrangement_red_2* red_arr,
const Arrangement_blue_2* blue_arr,
Arrangement_2* res_arr,
Overlay_traits* overlay_traits) :
Base(red_arr, blue_arr, res_arr, overlay_traits)
Base(red_arr, blue_arr, res_arr, overlay_traits),
m_found_x(false)
{}
/*! Destructor */
virtual ~Arr_do_intersect_overlay_ss_visitor() {}
// template <typename CurveIterator>
// void sweep(CurveIterator begin, CurveIterator end)
// { this->surface_sweep()->sweep(begin, end); }
// template <typename CurveIterator, typename PointIterator>
// void sweep(CurveIterator cvs_begin, CurveIterator cvs_end, PointIterator pts_begin, PointIterator pts_end)
// { this->surface_sweep()->sweep(cvs_begin, cvs_end, pts_begin, pts_end); }
/*! Update an event that corresponds to a curve endpoint. */
void update_event(Event* e, const Point_2& end_point, const X_monotone_curve_2& cv, Arr_curve_end cv_end, bool is_new)
{ return Base::update_event(e, end_point, cv, cv_end, is_new); }
/*! Update an event that corresponds to a curve endpoint */
void update_event(Event* e, const X_monotone_curve_2& cv, Arr_curve_end cv_end, bool is_new )
{ return Base::update_event(e, cv, cv_end, is_new); }
/*! Update an event that corresponds to a curve endpoint */
void update_event(Event* e, const Point_2& p, bool is_new)
{ return Base::update_event(e, p, is_new); }
/*! Update an event that corresponds to an intersection */
void update_event(Event*, Subcurve*) { m_found_x = true; }
/*! Update an event that corresponds to an intersection between curves */
void update_event(Event*, Subcurve*, Subcurve*, bool is_new) { m_found_x = true; }
/*! found an overlap */
void found_overlap(Subcurve*, Subcurve*, Subcurve*) { m_found_x = true; }
bool after_handle_event(Event* e, Status_line_iterator iter, bool flag) {
if (m_found_x) this->surface_sweep()->stop_sweep();
return Base::after_handle_event(e, iter, flag);
}
/*! Getter */
bool found_intersection() { return m_found_x; }
};
} // namespace CGAL

View File

@ -288,7 +288,7 @@ public:
if (this->is_plane() || other.is_plane()) return true;
Aos_2 res_arr;
Gps_do_intersect_functor<Aos_2> func;
do_intersect_overlay(*m_arr, *(other.m_arr), res_arr, func);
if (do_intersect_overlay(*m_arr, *(other.m_arr), res_arr, func)) return true;
return func.found_reg_intersection();
}

View File

@ -46,18 +46,18 @@ inline bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
Traits& traits)
{ return s_do_intersect(pgn1, pgn2, traits); }
// With Tag_true
template <typename Kernel, typename Container>
inline bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
const Polygon_2<Kernel, Container>& pgn2,
Tag_true = Tag_true())
{ return s_do_intersect(pgn1, pgn2); }
// With Tag_true is cancelled
// template <typename Kernel, typename Container>
// inline bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
// const Polygon_2<Kernel, Container>& pgn2,
// Tag_true)
// { return s_do_intersect(pgn1, pgn2); }
// With Tag_false
template <typename Kernel, typename Container>
inline bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
const Polygon_2<Kernel, Container>& pgn2,
Tag_false) {
Tag_false = Tag_false()) {
using Polygon = Polygon_2<Kernel, Container>;
typename Gps_default_traits<Polygon>::Traits traits;
return s_do_intersect(pgn1, pgn2, traits);
@ -71,18 +71,18 @@ inline bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
Traits& traits)
{ return s_do_intersect(pgn1, pgn2, traits); }
// With Tag_true
template <typename Kernel, typename Container>
inline bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
const Polygon_with_holes_2<Kernel, Container>& pgn2,
Tag_true = Tag_true())
{ return s_do_intersect(pgn1, pgn2); }
// With Tag_true is cancelled
// template <typename Kernel, typename Container>
// inline bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
// const Polygon_with_holes_2<Kernel, Container>& pgn2,
// Tag_true)
// { return s_do_intersect(pgn1, pgn2); }
// With Tag_false
template <typename Kernel, typename Container>
inline bool do_intersect(const Polygon_2<Kernel, Container>& pgn1,
const Polygon_with_holes_2<Kernel, Container>& pgn2,
Tag_false) {
Tag_false = Tag_false()) {
// Use the first polygon to determine the (default) traits
using Polygon = Polygon_2<Kernel, Container>;
typename Gps_default_traits<Polygon>::Traits traits;
@ -97,18 +97,18 @@ inline bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
Traits& traits)
{ return s_do_intersect(pgn1, pgn2, traits); }
// With Tag_true
template <typename Kernel, typename Container>
inline bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
const Polygon_2<Kernel, Container>& pgn2,
Tag_true = Tag_true())
{ return s_do_intersect(pgn1, pgn2); }
// With Tag_true is cancelled
// template <typename Kernel, typename Container>
// inline bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
// const Polygon_2<Kernel, Container>& pgn2,
// Tag_true)
// { return s_do_intersect(pgn1, pgn2); }
// With Tag_false
template <typename Kernel, typename Container>
inline bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
const Polygon_2<Kernel, Container>& pgn2,
Tag_false)
Tag_false = Tag_false())
{
// Use the first polygon to determine the (default) traits
using Polygon_with_holes = Polygon_with_holes_2<Kernel, Container>;
@ -124,18 +124,18 @@ inline bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
Traits& traits)
{ return s_do_intersect(pgn1, pgn2, traits); }
// With Tag_true
template <typename Kernel, typename Container>
inline bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
const Polygon_with_holes_2<Kernel, Container>& pgn2,
Tag_true = Tag_true())
{ return s_do_intersect(pgn1, pgn2); }
// With Tag_true is canclled
// template <typename Kernel, typename Container>
// inline bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
// const Polygon_with_holes_2<Kernel, Container>& pgn2,
// Tag_true)
// { return s_do_intersect(pgn1, pgn2); }
// With Tag_false
template <typename Kernel, typename Container>
inline bool do_intersect(const Polygon_with_holes_2<Kernel, Container>& pgn1,
const Polygon_with_holes_2<Kernel, Container>& pgn2,
Tag_false) {
Tag_false = Tag_false()) {
// Use the first polygon to determine the (default) traits
using Polygon_with_holes = Polygon_with_holes_2<Kernel, Container>;
typename Gps_default_traits<Polygon_with_holes>::Traits traits;
@ -233,21 +233,20 @@ inline bool do_intersect(InputIterator begin, InputIterator end, Traits& traits,
{ return r_do_intersect(begin, end, traits, k); }
// Without Traits
// Tag_true => convert to polylines
template <typename InputIterator>
inline bool do_intersect(InputIterator begin, InputIterator end,
Tag_true = Tag_true(), unsigned int k = 5,
std::enable_if_t<CGAL::is_iterator<InputIterator>::value>* = 0,
Enable_if_Polygon_2_iterator<InputIterator>* = 0)
{ return r_do_intersect(begin, end, k); }
// Tag_true => convert to polylines canclled
// template <typename InputIterator>
// inline bool do_intersect(InputIterator begin, InputIterator end,
// Tag_true, unsigned int k = 5,
// std::enable_if_t<CGAL::is_iterator<InputIterator>::value>* = 0,
// Enable_if_Polygon_2_iterator<InputIterator>* = 0)
// { return r_do_intersect(begin, end, k); }
// Tag_false => do not convert to polylines
template <typename InputIterator>
inline bool do_intersect(InputIterator begin, InputIterator end,
Tag_false, unsigned int k=5,
Tag_false = Tag_false(), unsigned int k = 5,
std::enable_if_t<CGAL::is_iterator<InputIterator>::value>* = 0,
Enable_if_Polygon_2_iterator<InputIterator>* = 0)
{
Enable_if_Polygon_2_iterator<InputIterator>* = 0) {
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
return r_do_intersect(begin, end, traits, k);
}
@ -255,10 +254,9 @@ inline bool do_intersect(InputIterator begin, InputIterator end,
// General polygons or polygons with holes
template <typename InputIterator>
inline bool do_intersect(InputIterator begin, InputIterator end,
unsigned int k=5,
unsigned int k = 5,
std::enable_if_t<CGAL::is_iterator<InputIterator>::value>* = 0,
Disable_if_Polygon_2_iterator<InputIterator>* = 0)
{
Disable_if_Polygon_2_iterator<InputIterator>* = 0) {
typename Iterator_to_gps_traits<InputIterator>::Traits traits;
return do_intersect(begin, end, traits, k);
}
@ -267,23 +265,23 @@ inline bool do_intersect(InputIterator begin, InputIterator end,
template <typename InputIterator1, typename InputIterator2, typename Traits>
inline bool do_intersect(InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
Traits& traits, unsigned int k=5)
Traits& traits, unsigned int k = 5)
{ return r_do_intersect(begin1, end1, begin2, end2, traits, k); }
// Without Traits
// Tag_true => convert to polylines
template <typename InputIterator1, typename InputIterator2>
inline bool do_intersect(InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
Tag_true = Tag_true(), unsigned int k=5,
Enable_if_Polygon_2_iterator<InputIterator1>* = 0)
{ return r_do_intersect(begin1, end1, begin2, end2, k); }
// Tag_true => convert to polylines cancelled
// template <typename InputIterator1, typename InputIterator2>
// inline bool do_intersect(InputIterator1 begin1, InputIterator1 end1,
// InputIterator2 begin2, InputIterator2 end2,
// Tag_true, unsigned int k = 5,
// Enable_if_Polygon_2_iterator<InputIterator1>* = 0)
// { return r_do_intersect(begin1, end1, begin2, end2, k); }
// Tag_false => do not convert to polylines
template <typename InputIterator1, typename InputIterator2>
inline bool do_intersect(InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
Tag_false, unsigned int k=5,
Tag_false = Tag_false(), unsigned int k = 5,
Enable_if_Polygon_2_iterator<InputIterator1>* = 0)
{ return r_do_intersect(begin1, end1, begin2, end2, k); }
@ -291,7 +289,7 @@ inline bool do_intersect(InputIterator1 begin1, InputIterator1 end1,
template <typename InputIterator1, typename InputIterator2>
inline bool do_intersect(InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
unsigned int k=5,
unsigned int k = 5,
Disable_if_Polygon_2_iterator<InputIterator1>* = 0)
{
typename Iterator_to_gps_traits<InputIterator1>::Traits traits;