Skip to content

Commit

Permalink
[fix] overlay threshold for sort_by_side
Browse files Browse the repository at this point in the history
Fixes: issue boostorg#1186
  • Loading branch information
barendgehrels committed Aug 23, 2023
1 parent 3755fab commit 0d5f1a0
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 14 deletions.
Expand Up @@ -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 <typename T>
struct common_approximately_equals_epsilon
{
static T value()
{
return T(100);
}
};

template <typename Point1, typename Point2, typename E>
inline bool approximately_equals(Point1 const& a, Point2 const& b,
E const& epsilon_multiplier)
Expand Down
Expand Up @@ -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
Expand Down
14 changes: 3 additions & 11 deletions include/boost/geometry/algorithms/detail/overlay/get_clusters.hpp
Expand Up @@ -35,28 +35,20 @@ namespace detail { namespace overlay
template <typename Tag = no_rescale_policy_tag, bool Integral = false>
struct sweep_equal_policy
{
private:
template <typename T>
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 <typename P>
static inline bool equals(P const& p1, P const& p2)
{
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>
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>();
T const limit = T(1) / common_approximately_equals_epsilon<T>::value();
return value > limit;
}
};
Expand Down
Expand Up @@ -325,7 +325,7 @@ public :
double
>::type;

ct_type const tolerance = 1000000000;
static auto const tolerance = common_approximately_equals_epsilon<ct_type>::value();

int offset = 0;
while (approximately_equals(point_from, turn.point, tolerance)
Expand Down
8 changes: 7 additions & 1 deletion test/algorithms/buffer/buffer_multi_polygon.cpp
Expand Up @@ -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_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);
#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_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);
Expand Down Expand Up @@ -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_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<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 if rescaling is used in combination with get_clusters
// 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);
#endif

Expand Down
6 changes: 6 additions & 0 deletions test/algorithms/overlay/overlay_cases.hpp
Expand Up @@ -1113,6 +1113,12 @@ static std::string issue_1108[2] =
"POLYGON((22 1,22 0,14 0,18 -1.2696790939262529996,12 0,22 1))"
};

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))",
Expand Down
3 changes: 3 additions & 0 deletions test/algorithms/set_operations/union/union.cpp
Expand Up @@ -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;
Expand Down

0 comments on commit 0d5f1a0

Please sign in to comment.