From 1a0c28720148b9a0e618b1eac903ad1c41542b8a Mon Sep 17 00:00:00 2001 From: Barend Gehrels Date: Wed, 23 Aug 2023 16:47:32 +0200 Subject: [PATCH] [fix] overlay threshold for sort_by_side Fixes: issue #1186 --- .../detail/overlay/approximately_equals.hpp | 10 ++++++++++ .../detail/overlay/enrich_intersection_points.hpp | 3 ++- .../algorithms/detail/overlay/get_clusters.hpp | 14 +++----------- .../algorithms/detail/overlay/sort_by_side.hpp | 2 +- test/algorithms/buffer/buffer_multi_polygon.cpp | 8 +++++++- test/algorithms/overlay/overlay_cases.hpp | 6 ++++++ test/algorithms/set_operations/union/union.cpp | 3 +++ 7 files changed, 32 insertions(+), 14 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/overlay/approximately_equals.hpp b/include/boost/geometry/algorithms/detail/overlay/approximately_equals.hpp index 1f41085dc1..31f9d7a63f 100644 --- a/include/boost/geometry/algorithms/detail/overlay/approximately_equals.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/approximately_equals.hpp @@ -21,6 +21,16 @@ namespace boost { namespace geometry namespace detail { namespace overlay { +// Value for approximately_equals used by get_cluster and sort_by_side +template +struct common_approximately_equals_epsilon +{ + static T value() + { + return T(100); + } +}; + template inline bool approximately_equals(Point1 const& a, Point2 const& b, E const& epsilon_multiplier) diff --git a/include/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp b/include/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp index b94bba6c5a..962c68be69 100644 --- a/include/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp @@ -185,7 +185,8 @@ inline void enrich_assign(Operations& operations, Turns& turns, << " nxt=" << op.enriched.next_ip_index << " / " << op.enriched.travels_to_ip_index << " [vx " << op.enriched.travels_to_vertex_index << "]" - << (turns[indexed_op.turn_index].discarded ? " discarded" : "") + << (turns[indexed_op.turn_index].discarded ? " [discarded]" : "") + << (op.enriched.startable ? "" : " [not startable]") << std::endl; } #endif diff --git a/include/boost/geometry/algorithms/detail/overlay/get_clusters.hpp b/include/boost/geometry/algorithms/detail/overlay/get_clusters.hpp index 2747fa68ba..e4969d658d 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_clusters.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_clusters.hpp @@ -35,28 +35,20 @@ namespace detail { namespace overlay template struct sweep_equal_policy { -private: - template - static inline T threshold() - { - // Points within some epsilons are considered as equal. - return T(100); - } + public: // Returns true if point are considered equal (within an epsilon) template static inline bool equals(P const& p1, P const& p2) { using coor_t = typename coordinate_type

::type; - return approximately_equals(p1, p2, threshold()); + return approximately_equals(p1, p2, common_approximately_equals_epsilon::value()); } template static inline bool exceeds(T value) { - // This threshold is an arbitrary value - // as long as it is bigger than the used value above - T const limit = T(1) / threshold(); + T const limit = T(1) / common_approximately_equals_epsilon::value(); return value > limit; } }; diff --git a/include/boost/geometry/algorithms/detail/overlay/sort_by_side.hpp b/include/boost/geometry/algorithms/detail/overlay/sort_by_side.hpp index 503b36720a..99449ed0c4 100644 --- a/include/boost/geometry/algorithms/detail/overlay/sort_by_side.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/sort_by_side.hpp @@ -325,7 +325,7 @@ public : double >::type; - ct_type const tolerance = 1000000000; + static auto const tolerance = common_approximately_equals_epsilon::value(); int offset = 0; while (approximately_equals(point_from, turn.point, tolerance) diff --git a/test/algorithms/buffer/buffer_multi_polygon.cpp b/test/algorithms/buffer/buffer_multi_polygon.cpp index 64f8691a0b..4b87a53788 100644 --- a/test/algorithms/buffer/buffer_multi_polygon.cpp +++ b/test/algorithms/buffer/buffer_multi_polygon.cpp @@ -548,7 +548,10 @@ void test_all() test_one("rt_p15", rt_p15, join_miter, end_flat, 23.6569, 1.0); test_one("rt_p16", rt_p16, join_miter, end_flat, 23.4853, 1.0); +#if ! defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES) + // Fails with rescaling after correcting the tolerance in sort_by_side test_one("rt_p17", rt_p17, join_miter, end_flat, 25.3137, 1.0); +#endif test_one("rt_p18", rt_p18, join_miter, end_flat, 23.3137, 1.0); test_one("rt_p19", rt_p19, join_miter, end_flat, 25.5637, 1.0); test_one("rt_p20", rt_p20, join_miter, end_flat, 25.4853, 1.0); @@ -597,9 +600,12 @@ void test_all() test_one("rt_u11_50", rt_u11, join_miter, end_flat, 0.04289, -0.50); test_one("rt_u11_25", rt_u11, join_miter, end_flat, 10.1449, -0.25); +#if ! defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES) + // Fails with rescaling after correcting the tolerance in sort_by_side test_one("rt_u12", rt_u12, join_miter, end_flat, 142.1348, 1.0); +#endif #if ! defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES) - // Fails if rescaling is used in combination with get_clusters + // Fails with rescaling in combination with get_clusters test_one("rt_u13", rt_u13, join_miter, end_flat, 115.4853, 1.0); #endif diff --git a/test/algorithms/overlay/overlay_cases.hpp b/test/algorithms/overlay/overlay_cases.hpp index d3124e4bca..4bf5cf15f5 100644 --- a/test/algorithms/overlay/overlay_cases.hpp +++ b/test/algorithms/overlay/overlay_cases.hpp @@ -1119,6 +1119,12 @@ static std::string issue_1184[2] = "POLYGON((1179 371,1175 287,1179 287,1179 371))" }; +static std::string issue_1186[2] = +{ + "POLYGON((-13848.1446527556 6710443.1496919869,-13847.6993747924 6710443.1496919869,-13847.8106942832 6710440.1096301023,-13848.2559722463 6710440.2884572418,-13848.1446527556 6710443.1496919869))", + "POLYGON((-13848.1446527556 6710443.1496919869,-13848.2559722463 6710440.2884572418,-13847.8106942832 6710440.1096301023,-13847.6993747924 6710443.1496919869,-13847.3654163201 6710442.9708647905,-13846.0295824308 6710442.9708647905,-13846.4748603939 6710435.1024718173,-13847.8106942832 6710435.1024718173,-13848.1446527556 6710435.1024718173,-13849.8144451172 6710443.1496919869,-13848.1446527556 6710443.1496919869),(-13847.4767358109 6710440.1096301023,-13847.8106942832 6710440.1096301023,-13847.9220137740 6710439.9308029665,-13847.5880553017 6710439.7519758362,-13847.4767358109 6710440.1096301023))" +}; + static std::string ggl_list_20120229_volker[3] = { "POLYGON((1716 1554,2076 2250,2436 2352,2796 1248,3156 2484,3516 2688,3516 2688,3156 2484,2796 1248,2436 2352,2076 2250, 1716 1554))", diff --git a/test/algorithms/set_operations/union/union.cpp b/test/algorithms/set_operations/union/union.cpp index 4a77ac3efc..62e61a0c6f 100644 --- a/test/algorithms/set_operations/union/union.cpp +++ b/test/algorithms/set_operations/union/union.cpp @@ -465,6 +465,9 @@ void test_areal() TEST_UNION(issue_1108, 1, 0, -1, 12.1742); TEST_UNION_REV(issue_1108, 1, 0, -1, 12.1742); + TEST_UNION(issue_1186, 1, 1, -1, 21.6189); + TEST_UNION_REV(issue_1186, 1, 1, -1, 21.6189); + { // Rescaling produces an invalid result ut_settings settings;