Skip to content

Commit

Permalink
Fix numerical issue for segments sharing a common point
Browse files Browse the repository at this point in the history
  • Loading branch information
vissarion committed Jan 10, 2024
1 parent fa36235 commit 265afa8
Show file tree
Hide file tree
Showing 15 changed files with 64 additions and 40 deletions.
8 changes: 8 additions & 0 deletions include/boost/geometry/policies/relate/direction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,14 @@ struct segments_direction
;
}

template <typename SegmentIntersectionInfo, typename Point>
static inline return_type segments_share_common_point(side_info const& sides,
SegmentIntersectionInfo const& ,
Point const&)
{
return segments_crosses(sides, sides, sides, sides);
}

template <typename Ratio>
static inline int arrival_value(Ratio const& r_from, Ratio const& r_to)
{
Expand Down
16 changes: 16 additions & 0 deletions include/boost/geometry/policies/relate/intersection_points.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <algorithm>
#include <string>

#include <boost/geometry/algorithms/assign.hpp>
#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/assert.hpp>
Expand Down Expand Up @@ -61,6 +62,21 @@ struct segments_intersection_points
return result;
}

template<typename SegmentIntersectionInfo, typename Point>
static inline return_type
segments_share_common_point(side_info const&, SegmentIntersectionInfo const& sinfo,
Point const& p)
{
return_type result;
result.count = 1;
boost::geometry::assign(result.intersections[0], p);

// Temporary - this should go later
result.fractions[0].assign(sinfo);

return result;
}

template <typename Segment1, typename Segment2, typename Ratio>
static inline return_type segments_collinear(
Segment1 const& a, Segment2 const& b, bool /*opposite*/,
Expand Down
13 changes: 13 additions & 0 deletions include/boost/geometry/policies/relate/intersection_policy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,19 @@ struct segments_intersection_policy
);
}

template <typename SegmentIntersectionInfo, typename Point>
static inline return_type
segments_share_common_point(side_info const& sides,
SegmentIntersectionInfo const& sinfo,
Point const& p)
{
return return_type
(
pts_policy::segments_share_common_point(sides, sinfo, p),
dir_policy::segments_share_common_point(sides, sinfo, p)
);
}

template <typename Segment1, typename Segment2, typename Ratio>
static inline return_type segments_collinear(
Segment1 const& segment1,
Expand Down
10 changes: 10 additions & 0 deletions include/boost/geometry/policies/relate/intersection_ratios.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,16 @@ struct segments_intersection_ratios
return result;
}

template<typename SegmentIntersectionInfo, typename Point>
static inline return_type
segments_share_common_point(side_info const&, SegmentIntersectionInfo const& sinfo,
Point const& p)
{
return_type result;
result.assign(sinfo);
return result;
}

template <typename Segment1, typename Segment2, typename Ratio>
static inline return_type segments_collinear(
Segment1 const& , Segment2 const& ,
Expand Down
11 changes: 11 additions & 0 deletions include/boost/geometry/strategies/cartesian/intersection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,7 @@ struct cartesian_segments

bool collinear = sides.collinear();

//TODO: remove this
// Calculate the differences again
// (for rescaled version, this is different from dx_p etc)
coordinate_type const dx_p = get<0>(p2) - get<0>(p1);
Expand Down Expand Up @@ -533,6 +534,16 @@ struct cartesian_segments
}
}

if (equals_point_point(p1, q1) || equals_point_point(p1, q2))
{
return Policy::segments_share_common_point(sides, sinfo, p1);
}

if (equals_point_point(p2, q1) || equals_point_point(p2, q2))
{
return Policy::segments_share_common_point(sides, sinfo, p2);
}

return Policy::segments_crosses(sides, sinfo, p, q);
}

Expand Down
3 changes: 0 additions & 3 deletions test/algorithms/Jamfile
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@ test-suite boost-geometry-algorithms
[ run is_valid.cpp : : : : algorithms_is_valid ]
[ run is_valid_failure.cpp : : : : algorithms_is_valid_failure ]
[ run is_valid_geo.cpp : : : : algorithms_is_valid_geo ]
[ run is_valid.cpp : : : <define>BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_is_valid_alternative ]
[ run is_valid_failure.cpp : : : <define>BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_is_valid_failure_alternative ]
[ run is_valid_geo.cpp : : : <define>BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_is_valid_geo_alternative ]
[ run line_interpolate.cpp : : : : algorithms_line_interpolate ]
[ run make.cpp : : : : algorithms_make ]
[ run maximum_gap.cpp : : : : algorithms_maximum_gap ]
Expand Down
7 changes: 0 additions & 7 deletions test/algorithms/buffer/Jamfile
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,6 @@ test-suite boost-geometry-algorithms-buffer
[ run buffer_multi_polygon_geo.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_buffer_multi_polygon_geo ]
[ run buffer_geo_spheroid.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_buffer_geo_spheroid ]
[ run buffer_linestring_aimes.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_buffer_linestring_aimes ]
[ run buffer_linestring.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE <define>BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_buffer_linestring_alternative ]
[ run buffer_multi_linestring.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE <define>BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_buffer_multi_linestring_alternative ]
[ run buffer_ring.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE <define>BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_buffer_ring_alternative ]
[ run buffer_polygon.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE <define>BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_buffer_polygon_alternative ]
[ run buffer_multi_point.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE <define>BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_buffer_multi_point_alternative ]
[ run buffer_multi_polygon.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE <define>BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_buffer_multi_polygon_alternative ]
[ run buffer_linestring_aimes.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE <define>BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_buffer_linestring_aimes_alternative ]
# Uncomment next lines if you want to test this manually; requires access to data/ folder
# [ run buffer_countries.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_buffer_countries ]
# [ run buffer_countries.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE <define>BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_buffer_countries_alternative ]
Expand Down
4 changes: 0 additions & 4 deletions test/algorithms/convex_hull/Jamfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,4 @@ test-suite boost-geometry-algorithms-convex_hull
[ run convex_hull_multi.cpp : : : : algorithms_convex_hull_multi ]
[ run convex_hull_robust.cpp : : : : algorithms_convex_hull_robust ]
[ run convex_hull_sph_geo.cpp : : : : algorithms_convex_hull_sph_geo ]
[ run convex_hull.cpp : : : <define>BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_convex_hull_alternative ]
[ run convex_hull_multi.cpp : : : <define>BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_convex_hull_multi_alternative ]
[ run convex_hull_robust.cpp : : : <define>BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_convex_hull_robust_alternative ]
[ run convex_hull_sph_geo.cpp : : : <define>BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_convex_hull_sph_geo_alternative ]
;
8 changes: 1 addition & 7 deletions test/algorithms/is_simple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,14 +263,8 @@ BOOST_AUTO_TEST_CASE( test_geometry_with_NaN_coordinates )
std::cout << "************************************" << std::endl;
#endif

linestring_type ls1, ls2;
bg::read_wkt("LINESTRING(1 1,1.115235e+308 1.738137e+308)", ls1);
bg::read_wkt("LINESTRING(-1 1,1.115235e+308 1.738137e+308)", ls2);

// the intersection of the two linestrings is a new linestring
// (multilinestring with a single element) that has NaN coordinates
multi_linestring_type mls;
bg::intersection(ls1, ls2, mls);
bg::read_wkt("MULTILINESTRING((nan nan))", mls);

test_simple(mls, true, false);
}
Expand Down
8 changes: 1 addition & 7 deletions test/algorithms/is_valid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1433,14 +1433,8 @@ BOOST_AUTO_TEST_CASE( test_with_NaN_coordinates )
std::cout << "************************************" << std::endl;
#endif

linestring_type ls1, ls2;
bg::read_wkt("LINESTRING(1 1,1.115235e+308 1.738137e+308)", ls1);
bg::read_wkt("LINESTRING(-1 1,1.115235e+308 1.738137e+308)", ls2);

// the intersection of the two linestrings is a new linestring
// (multilinestring with a single element) that has NaN coordinates
multi_linestring_type mls;
bg::intersection(ls1, ls2, mls);
bg::read_wkt("MULTILINESTRING((nan nan))", mls);

typedef validity_tester_linear<true> tester_allow_spikes;
typedef validity_tester_linear<false> tester_disallow_spikes;
Expand Down
3 changes: 1 addition & 2 deletions test/algorithms/overlay/Jamfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# http://www.boost.org/LICENSE_1_0.txt)

test-suite boost-geometry-algorithms-overlay
:
:
[ run assemble.cpp : : : : algorithms_assemble ]
[ run copy_segment_point.cpp : : : : algorithms_copy_segment_point ]
[ run get_clusters.cpp : : : : algorithms_get_clusters ]
Expand All @@ -28,7 +28,6 @@ test-suite boost-geometry-algorithms-overlay
[ run get_turns_linear_areal.cpp : : : : algorithms_get_turns_linear_areal ]
[ run get_turns_linear_areal_sph.cpp : : : : algorithms_get_turns_linear_areal_sph ]
[ run get_turns_linear_linear.cpp : : : : algorithms_get_turns_linear_linear ]
[ run get_turns_linear_linear.cpp : : : <define>BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_get_turns_linear_linear_alternative ]
[ run get_turns_linear_linear_geo.cpp : : : : algorithms_get_turns_linear_linear_geo ]
[ run get_turns_linear_linear_sph.cpp : : : : algorithms_get_turns_linear_linear_sph ]
[ run overlay.cpp : : : : algorithms_overlay ]
Expand Down
2 changes: 0 additions & 2 deletions test/algorithms/set_operations/difference/Jamfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ test-suite boost-geometry-algorithms-difference
:
[ run difference.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_difference ]
[ run difference_multi.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_difference_multi ]
[ run difference.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE <define>BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_difference_alternative ]
[ run difference_multi.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE <define>BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_difference_multi_alternative ]
[ run difference_multi_spike.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_difference_multi_spike ]
[ run difference_areal_linear.cpp : : : : algorithms_difference_areal_linear ]
[ run difference_gc.cpp : : : : algorithms_difference_gc ]
Expand Down
3 changes: 0 additions & 3 deletions test/algorithms/set_operations/intersection/Jamfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,7 @@ test-suite boost-geometry-algorithms-intersection
:
[ run intersection.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_intersection ]
[ run intersection_multi.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_intersection_multi ]
[ run intersection.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE <define>BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_intersection_alternative ]
[ run intersection_multi.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE <define>BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_intersection_multi_alternative ]
[ run intersection_linear_linear.cpp : : : : algorithms_intersection_linear_linear ]
[ run intersection_linear_linear.cpp : : : <define>BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_intersection_linear_linear_alternative ]
[ run intersection_areal_areal_linear.cpp : : : : algorithms_intersection_areal_areal_linear ]
[ run intersection_box.cpp : : : : algorithms_intersection_box ]
[ run intersection_gc.cpp : : : : algorithms_intersection_gc ]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1300,7 +1300,7 @@ BOOST_AUTO_TEST_CASE( test_intersection_ml_ml_degenerate )
// NOTE: if get_turn_info uses policy_verify_all then the result is different

#if BOOST_GEOMETRY_INTERSECTION_DO_NOT_INCLUDE_ISOLATED_POINTS
from_wkt<ML>("MULTILINESTRING((-0.7654 8.88178e-16,-0.7654 0,5 3))"),
from_wkt<ML>("MULTILINESTRING((-0.7654 0,5 3))"),
#else
from_wkt<ML>("MULTILINESTRING((-0.756651 3.30964),(1.60494 6),\
(2.51371 6),(3.26673 6),(4 6),(8.18862 3.07616),\
Expand Down Expand Up @@ -1337,7 +1337,7 @@ BOOST_AUTO_TEST_CASE( test_intersection_ml_ml_degenerate )
(8.5655 2.85228),(5.26567 4.81254),(4 3.8),\
(1.4995 3.27036),(0.591231 3.43401),\
(-0.706503 3.66784),\
(-0.7654 8.88178e-16,-0.7654 0,5 3))"),
(-0.7654 0,5 3))"),
from_wkt<ML>("MULTILINESTRING((1.87562 6.68515),(1.60494 6),\
(1.18124 4.9275),(1.00439 4.47984),(0.91526 4.25422),\
(0.729883 3.78498),(0.614728 3.49349),\
Expand Down Expand Up @@ -1368,7 +1368,7 @@ BOOST_AUTO_TEST_CASE( test_intersection_ml_ml_degenerate )
(9.98265 0.00543606),(9.09826 -100.515944),\
(7.08745 -329.0674155),(5.06428 -559.024344),\
(3.23365 -767.0972558),(3.16036 -775.427199),\
(-0.7654 8.88178e-16,-0.7654 0,5 3))"),
(-0.7654 0,5 3))"),
#endif // isolated
"mlmli21",
1e-4
Expand Down
2 changes: 0 additions & 2 deletions test/algorithms/set_operations/union/Jamfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ test-suite boost-geometry-algorithms-union
:
[ run union.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_union ]
[ run union_multi.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_union_multi ]
[ run union.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE <define>BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_union_alternative ]
[ run union_multi.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE <define>BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_union_multi_alternative ]
[ run union_aa_geo.cpp : : : : algorithms_union_aa_geo ]
[ run union_aa_sph.cpp : : : : algorithms_union_aa_sph ]
[ run union_gc.cpp : : : : algorithms_union_gc ]
Expand Down

0 comments on commit 265afa8

Please sign in to comment.