[fix] overlay threshold for sort_by_side

Fixes: issue #1186
This commit is contained in:
Barend Gehrels 2023-08-23 16:47:32 +02:00
parent 88ea9049ff
commit fd209ffbf5
7 changed files with 33 additions and 15 deletions

View File

@ -21,6 +21,16 @@ namespace boost { namespace geometry
namespace detail { namespace overlay namespace detail { namespace overlay
{ {
// Value for approximately_equals used by get_cluster and sort_by_side
template <typename T>
struct common_approximately_equals_epsilon
{
static T value()
{
return T(100);
}
};
template <typename Point1, typename Point2, typename E> template <typename Point1, typename Point2, typename E>
inline bool approximately_equals(Point1 const& a, Point2 const& b, inline bool approximately_equals(Point1 const& a, Point2 const& b,
E const& epsilon_multiplier) E const& epsilon_multiplier)

View File

@ -185,7 +185,8 @@ inline void enrich_assign(Operations& operations, Turns& turns,
<< " nxt=" << op.enriched.next_ip_index << " nxt=" << op.enriched.next_ip_index
<< " / " << op.enriched.travels_to_ip_index << " / " << op.enriched.travels_to_ip_index
<< " [vx " << op.enriched.travels_to_vertex_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; << std::endl;
} }
#endif #endif

View File

@ -35,28 +35,20 @@ namespace detail { namespace overlay
template <typename Tag = no_rescale_policy_tag, bool Integral = false> template <typename Tag = no_rescale_policy_tag, bool Integral = false>
struct sweep_equal_policy struct sweep_equal_policy
{ {
private:
template <typename T>
static inline T threshold()
{
// Points within some epsilons are considered as equal.
return T(100);
}
public: public:
// Returns true if point are considered equal (within an epsilon) // Returns true if point are considered equal (within an epsilon)
template <typename P> template <typename P>
static inline bool equals(P const& p1, P const& p2) static inline bool equals(P const& p1, P const& p2)
{ {
using coor_t = typename coordinate_type<P>::type; using coor_t = typename coordinate_type<P>::type;
return approximately_equals(p1, p2, threshold<coor_t>()); return approximately_equals(p1, p2, common_approximately_equals_epsilon<coor_t>::value());
} }
template <typename T> template <typename T>
static inline bool exceeds(T value) static inline bool exceeds(T value)
{ {
// This threshold is an arbitrary value T const limit = T(1) / common_approximately_equals_epsilon<T>::value();
// as long as it is bigger than the used value above
T const limit = T(1) / threshold<T>();
return value > limit; return value > limit;
} }
}; };

View File

@ -325,7 +325,7 @@ public :
double double
>::type; >::type;
ct_type const tolerance = 1000000000; static auto const tolerance = common_approximately_equals_epsilon<ct_type>::value();
int offset = 0; int offset = 0;
while (approximately_equals(point_from, turn.point, tolerance) while (approximately_equals(point_from, turn.point, tolerance)

View File

@ -548,7 +548,10 @@ void test_all()
test_one<multi_polygon_type, polygon_type>("rt_p15", rt_p15, join_miter, end_flat, 23.6569, 1.0); test_one<multi_polygon_type, polygon_type>("rt_p15", rt_p15, join_miter, end_flat, 23.6569, 1.0);
test_one<multi_polygon_type, polygon_type>("rt_p16", rt_p16, join_miter, end_flat, 23.4853, 1.0); test_one<multi_polygon_type, polygon_type>("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<multi_polygon_type, polygon_type>("rt_p17", rt_p17, join_miter, end_flat, 25.3137, 1.0); test_one<multi_polygon_type, polygon_type>("rt_p17", rt_p17, join_miter, end_flat, 25.3137, 1.0);
#endif
test_one<multi_polygon_type, polygon_type>("rt_p18", rt_p18, join_miter, end_flat, 23.3137, 1.0); test_one<multi_polygon_type, polygon_type>("rt_p18", rt_p18, join_miter, end_flat, 23.3137, 1.0);
test_one<multi_polygon_type, polygon_type>("rt_p19", rt_p19, join_miter, end_flat, 25.5637, 1.0); test_one<multi_polygon_type, polygon_type>("rt_p19", rt_p19, join_miter, end_flat, 25.5637, 1.0);
test_one<multi_polygon_type, polygon_type>("rt_p20", rt_p20, join_miter, end_flat, 25.4853, 1.0); test_one<multi_polygon_type, polygon_type>("rt_p20", rt_p20, join_miter, end_flat, 25.4853, 1.0);
@ -597,9 +600,12 @@ void test_all()
test_one<multi_polygon_type, polygon_type>("rt_u11_50", rt_u11, join_miter, end_flat, 0.04289, -0.50); test_one<multi_polygon_type, polygon_type>("rt_u11_50", rt_u11, join_miter, end_flat, 0.04289, -0.50);
test_one<multi_polygon_type, polygon_type>("rt_u11_25", rt_u11, join_miter, end_flat, 10.1449, -0.25); test_one<multi_polygon_type, polygon_type>("rt_u11_25", rt_u11, join_miter, end_flat, 10.1449, -0.25);
test_one<multi_polygon_type, polygon_type>("rt_u12", rt_u12, join_miter, end_flat, 142.1348, 1.0);
#if ! defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES) #if ! defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES)
// Fails if rescaling is used in combination with get_clusters // Fails with rescaling after correcting the tolerance in sort_by_side
test_one<multi_polygon_type, polygon_type>("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 with rescaling in combination with get_clusters
test_one<multi_polygon_type, polygon_type>("rt_u13", rt_u13, join_miter, end_flat, 115.4853, 1.0); test_one<multi_polygon_type, polygon_type>("rt_u13", rt_u13, join_miter, end_flat, 115.4853, 1.0);
#endif #endif

View File

@ -1119,6 +1119,12 @@ static std::string issue_1184[2] =
"POLYGON((1179 371,1175 287,1179 287,1179 371))" "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] = 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))", "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))",

View File

@ -465,6 +465,9 @@ void test_areal()
TEST_UNION(issue_1108, 1, 0, -1, 12.1742); TEST_UNION(issue_1108, 1, 0, -1, 12.1742);
TEST_UNION_REV(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 // Rescaling produces an invalid result
ut_settings settings; ut_settings settings;