handle cases where multiple endpoints are colinear as non-intersecting for line segments (because otherwise it cannot be used to check if intersection() has undefined behaviour, as there will be an infinite number of intersections)
This commit is contained in:
parent
95ce5ba03d
commit
69a360c48f
2 changed files with 10 additions and 4 deletions
|
@ -398,9 +398,13 @@ inline bool contains(const std::vector<GeometryA<T>>& multigeo,
|
|||
// _____________________________________________________________________________
|
||||
template <typename T>
|
||||
inline bool intersects(const LineSegment<T>& ls1, const LineSegment<T>& ls2) {
|
||||
// two line segments intersect of there is a single, well-defined intersection
|
||||
// point between them. If more than 1 endpoint is colinear with any line,
|
||||
// the segments have infinite intersections. We handle this case as non-
|
||||
// intersecting
|
||||
return intersects(getBoundingBox(ls1), getBoundingBox(ls2)) &&
|
||||
(contains(ls1.first, ls2) || contains(ls1.second, ls2) ||
|
||||
contains(ls2.first, ls1) || contains(ls2.second, ls1) ||
|
||||
(((contains(ls1.first, ls2) ^ contains(ls1.second, ls2)) ^
|
||||
(contains(ls2.first, ls1) ^ contains(ls2.second, ls1))) ||
|
||||
(((crossProd(ls1.first, ls2) < 0) ^
|
||||
(crossProd(ls1.second, ls2) < 0)) &&
|
||||
((crossProd(ls2.first, ls1) < 0) ^
|
||||
|
|
|
@ -972,12 +972,14 @@ CASE("geometry") {
|
|||
|
||||
EXPECT(geo::intersects(lsa, lsb));
|
||||
|
||||
EXPECT(geo::intersects(lsa, lsa));
|
||||
EXPECT(geo::intersects(lsb, lsb));
|
||||
EXPECT(!geo::intersects(lsa, lsa));
|
||||
EXPECT(!geo::intersects(lsb, lsb));
|
||||
EXPECT(!geo::intersects(lsa, lsc));
|
||||
|
||||
EXPECT(!geo::intersects(geo::Point<double>(871569.2, 6104550.4), geo::Point<double>(871581.2, 6104536), geo::Point<double>(871580.3, 6104541.3), geo::Point<double>(871625.7, 6104510.1)));
|
||||
|
||||
EXPECT(!geo::intersects(geo::Point<double>(0, 0), geo::Point<double>(1, 1), geo::Point<double>(0.5, 0.5), geo::Point<double>(1.5, 1.5)));
|
||||
|
||||
geo::Line<double> l{geo::Point<double>(1, 1), geo::Point<double>(2, 2), geo::Point<double>(2, 4)};
|
||||
EXPECT(!geo::contains(geo::Point<double>(1, 2), l));
|
||||
EXPECT(geo::contains(geo::Point<double>(2, 2), l));
|
||||
|
|
Loading…
Reference in a new issue