From b7d466c3f41847f0b186ab3386f92a5dc310fec3 Mon Sep 17 00:00:00 2001 From: fhamonic Date: Sun, 6 Oct 2024 03:51:10 +0200 Subject: [PATCH] bentley-ottmann traits --- include/melon/algorithm/bentley_ottmann.hpp | 69 ++++++++------------- test/bentley_ottmann_test.cpp | 6 +- 2 files changed, 31 insertions(+), 44 deletions(-) diff --git a/include/melon/algorithm/bentley_ottmann.hpp b/include/melon/algorithm/bentley_ottmann.hpp index abe896d..c634ef4 100644 --- a/include/melon/algorithm/bentley_ottmann.hpp +++ b/include/melon/algorithm/bentley_ottmann.hpp @@ -26,32 +26,22 @@ #include "melon/utility/algorithmic_generator.hpp" #include "melon/utility/geometry.hpp" -namespace std { -template -struct hash> { - std::size_t operator()(const fhamonic::melon::rational & r) const { - r.normalize(); - std::size_t h1 = std::hash()(r.num); - std::size_t h2 = std::hash()(r.den); - return h1 ^ (h2 + 0x9e3779b9 + (h1 << 6) + (h1 >> 2)); - } +namespace fhamonic { +namespace melon { + +// clang-format off +template +concept bentley_ottmann_traits = requires() { + { _Traits::report_endpoints } -> std::convertible_to; }; -template -struct hash< - std::pair, fhamonic::melon::rational>> { - std::size_t operator()( - const std::pair, - fhamonic::melon::rational> & p) const { - std::size_t h1 = std::hash>()(p.first); - std::size_t h2 = std::hash>()(p.second); - return h1 ^ (h2 + 0x9e3779b9 + (h1 << 6) + (h1 >> 2)); - } +// clang-format on + +template +struct default_bentley_ottmann_traits { + static constexpr bool report_endpoints = true; }; -} // namespace std -namespace fhamonic { -namespace melon { -template > _SegmentMap = views::identity_map> class bentley_ottmann { @@ -130,8 +120,8 @@ class bentley_ottmann { enum event_type { starting, ending, coincident }; using events = std::vector>; - // using events_map = std::unordered_map; - using events_map = std::map; + using events_map = + std::map; private: _SegmentIdRange _segments_ids_range; @@ -247,18 +237,6 @@ class bentley_ottmann { push_intersection(i); } - bool well_formed_tree() const { - auto it = _segment_tree.begin(); - if(it == _segment_tree.end()) return true; - auto next = std::next(it); - while(next != _segment_tree.end()) { - if(!_segment_tree.key_comp()(*it, *next)) return false; - it = next; - next = std::next(next); - } - return true; - } - void handle_event(const std::pair & e) noexcept { const auto & [i, evts] = e; segment_tree tmp_tree(segment_cmp{i}); @@ -281,8 +259,10 @@ class bentley_ottmann { _segment_tree.extract(tree_it)); tree_it = std::move(next_it); } - for(const auto & [s, et] : evts) { - _intersections.emplace_back(s); + if constexpr(_Traits::report_endpoints) { + for(const auto & [s, et] : evts) { + _intersections.emplace_back(s); + } } } _current_event_point = i; @@ -364,13 +344,18 @@ class bentley_ottmann { template bentley_ottmann(_SegmentIdRange &&) - -> bentley_ottmann, + -> bentley_ottmann>, + std::ranges::views::all_t<_SegmentIdRange>, views::identity_map>; template bentley_ottmann(_SegmentIdRange &&, _SegmentMap &&) - -> bentley_ottmann, - views::mapping_all_t<_SegmentMap>>; + -> bentley_ottmann< + default_bentley_ottmann_traits>>, + std::ranges::views::all_t<_SegmentIdRange>, + views::mapping_all_t<_SegmentMap>>; } // namespace melon } // namespace fhamonic diff --git a/test/bentley_ottmann_test.cpp b/test/bentley_ottmann_test.cpp index 8b656e1..0e32570 100755 --- a/test/bentley_ottmann_test.cpp +++ b/test/bentley_ottmann_test.cpp @@ -19,7 +19,9 @@ template auto naive_intersections(const std::vector segments) { using intersection = decltype(cartesian::segments_intersection( std::declval(), std::declval()))::value_type; - std::unordered_map> intersections_map; + std::map, + cartesian::point_xy_comparator> + intersections_map; auto point_eq = [](const auto & p1, const auto & p2) { return std::get<0>(p1) == std::get<0>(p2) && @@ -183,7 +185,7 @@ GTEST_TEST(bentley_ottmann, fuzzy_test) { // fmt::join(intersecting_segments, " , ")); } const std::size_t num_intersections = intersections_vec.size(); - num_intersection_sum += num_intersections; + // num_intersection_sum += num_intersections; auto naive_intersections_vec = naive_intersections(segments); ASSERT_TRUE(EQ_MULTISETS(std::views::keys(intersections_vec),