mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-05-26 17:36:40 +08:00
refactor: remove SegSegResult enum and replace by bool
it was only used to test against ::Proper so no functionality is lost. Tests are adapted accordingly
This commit is contained in:
@@ -37,7 +37,6 @@
|
||||
|
||||
using namespace matrix;
|
||||
|
||||
using geofence_utils::SegSegResult;
|
||||
|
||||
TEST(GeofenceUtilsTest, Orient2d)
|
||||
{
|
||||
@@ -57,7 +56,7 @@ TEST(GeofenceUtilsTest, SegmentsSharedEndpointNoIntersection)
|
||||
Vector2f v1(1.f, 1.f);
|
||||
Vector2f v2(2.f, 2.f);
|
||||
|
||||
EXPECT_EQ(SegSegResult::CollinearOverlap, geofence_utils::segmentsIntersect(p1, p2, v1, v2));
|
||||
EXPECT_FALSE(geofence_utils::segmentsIntersect(p1, p2, v1, v2));
|
||||
}
|
||||
|
||||
TEST(GeofenceUtilsTest, SegmentsCross)
|
||||
@@ -69,7 +68,7 @@ TEST(GeofenceUtilsTest, SegmentsCross)
|
||||
Vector2f v1(-0.0001f, 0.0001f);
|
||||
Vector2f v2(1.f, 0.0001f);
|
||||
|
||||
EXPECT_EQ(SegSegResult::Proper, geofence_utils::segmentsIntersect(p1, p2, v1, v2));
|
||||
EXPECT_TRUE(geofence_utils::segmentsIntersect(p1, p2, v1, v2));
|
||||
}
|
||||
|
||||
TEST(GeofenceUtilsTest, SegmentsTouching)
|
||||
@@ -82,17 +81,17 @@ TEST(GeofenceUtilsTest, SegmentsTouching)
|
||||
Vector2f v1(0.f, 1.0f);
|
||||
Vector2f v2(1.f, 1.0f);
|
||||
|
||||
// Endpoint v1 of segment cd lies on the open segment ab. Symmetric in
|
||||
// argument order: the convention-laden asymmetry of the old API is gone.
|
||||
EXPECT_EQ(SegSegResult::Touching, geofence_utils::segmentsIntersect(p1, p2, v1, v2));
|
||||
EXPECT_EQ(SegSegResult::Touching, geofence_utils::segmentsIntersect(v1, v2, p1, p2));
|
||||
// Endpoint v1 of segment cd lies on the open segment ab. segmentsIntersect
|
||||
// only flags proper crossings, so an endpoint touch returns false.
|
||||
EXPECT_FALSE(geofence_utils::segmentsIntersect(p1, p2, v1, v2));
|
||||
EXPECT_FALSE(geofence_utils::segmentsIntersect(v1, v2, p1, p2));
|
||||
|
||||
// Same, but with vertical line slanted for good measure
|
||||
p1(0) = -1.0f;
|
||||
p2(0) = 1.0f;
|
||||
|
||||
EXPECT_EQ(SegSegResult::Touching, geofence_utils::segmentsIntersect(p1, p2, v1, v2));
|
||||
EXPECT_EQ(SegSegResult::Touching, geofence_utils::segmentsIntersect(v1, v2, p1, p2));
|
||||
EXPECT_FALSE(geofence_utils::segmentsIntersect(p1, p2, v1, v2));
|
||||
EXPECT_FALSE(geofence_utils::segmentsIntersect(v1, v2, p1, p2));
|
||||
}
|
||||
|
||||
TEST(GeofenceUtilsTest, SegmentsParallel)
|
||||
@@ -104,11 +103,11 @@ TEST(GeofenceUtilsTest, SegmentsParallel)
|
||||
Vector2f v2(40.f, 20.f);
|
||||
|
||||
// Disjoint, non-collinear: no intersection.
|
||||
EXPECT_EQ(SegSegResult::None, geofence_utils::segmentsIntersect(p1, p2, v1, v2));
|
||||
EXPECT_FALSE(geofence_utils::segmentsIntersect(p1, p2, v1, v2));
|
||||
|
||||
// A segment with itself is fully collinear-overlapping.
|
||||
EXPECT_EQ(SegSegResult::CollinearOverlap, geofence_utils::segmentsIntersect(p1, p2, p1, p2));
|
||||
EXPECT_EQ(SegSegResult::CollinearOverlap, geofence_utils::segmentsIntersect(v1, v2, v1, v2));
|
||||
// A segment with itself is collinear-overlapping, not a proper crossing.
|
||||
EXPECT_FALSE(geofence_utils::segmentsIntersect(p1, p2, p1, p2));
|
||||
EXPECT_FALSE(geofence_utils::segmentsIntersect(v1, v2, v1, v2));
|
||||
}
|
||||
|
||||
TEST(GeofenceUtilsTest, SegmentsCollinearDisjoint)
|
||||
@@ -117,7 +116,7 @@ TEST(GeofenceUtilsTest, SegmentsCollinearDisjoint)
|
||||
Vector2f a(0.f, 0.f), b(1.f, 0.f);
|
||||
Vector2f c(2.f, 0.f), d(3.f, 0.f);
|
||||
|
||||
EXPECT_EQ(SegSegResult::None, geofence_utils::segmentsIntersect(a, b, c, d));
|
||||
EXPECT_FALSE(geofence_utils::segmentsIntersect(a, b, c, d));
|
||||
}
|
||||
|
||||
TEST(GeofenceUtilsTest, SegmentPolygonExclusionOutside)
|
||||
|
||||
@@ -78,41 +78,17 @@ bool insideCircle(const matrix::Vector2<double> ¢er, float radius,
|
||||
}
|
||||
|
||||
// O'Rourke, "Computational Geometry in C" (2nd ed.), section 1.5: SegSegInt.
|
||||
// Classifies a segment-segment intersection from the four orient2d signs of
|
||||
// the endpoints. No asymmetric strict/non-strict tolerance convention is
|
||||
// baked in -- the caller decides which variants count as "intersecting".
|
||||
SegSegResult segmentsIntersect(const matrix::Vector2f &a, const matrix::Vector2f &b,
|
||||
const matrix::Vector2f &c, const matrix::Vector2f &d)
|
||||
// True iff each segment strictly straddles the other's supporting line; this
|
||||
// excludes endpoint-touching and collinear overlap.
|
||||
bool segmentsIntersect(const matrix::Vector2f &a, const matrix::Vector2f &b,
|
||||
const matrix::Vector2f &c, const matrix::Vector2f &d)
|
||||
{
|
||||
const int o1 = orient2d(a, b, c);
|
||||
const int o2 = orient2d(a, b, d);
|
||||
const int o3 = orient2d(c, d, a);
|
||||
const int o4 = orient2d(c, d, b);
|
||||
|
||||
// Each segment strictly straddles the other's supporting line.
|
||||
if (o1 && o2 && o3 && o4 && o1 != o2 && o3 != o4) {
|
||||
return SegSegResult::Proper;
|
||||
}
|
||||
|
||||
// All four points collinear: overlap iff any endpoint of one lies on the other.
|
||||
if (!o1 && !o2 && !o3 && !o4) {
|
||||
if (collinearBetween(a, b, c) || collinearBetween(a, b, d) ||
|
||||
collinearBetween(c, d, a) || collinearBetween(c, d, b)) {
|
||||
return SegSegResult::CollinearOverlap;
|
||||
}
|
||||
|
||||
return SegSegResult::None;
|
||||
}
|
||||
|
||||
// One endpoint sits on the other segment.
|
||||
if ((!o1 && collinearBetween(a, b, c)) ||
|
||||
(!o2 && collinearBetween(a, b, d)) ||
|
||||
(!o3 && collinearBetween(c, d, a)) ||
|
||||
(!o4 && collinearBetween(c, d, b))) {
|
||||
return SegSegResult::Touching;
|
||||
}
|
||||
|
||||
return SegSegResult::None;
|
||||
return o1 && o2 && o3 && o4 && o1 != o2 && o3 != o4;
|
||||
}
|
||||
|
||||
// Is point P strictly inside the CCW/CW interior wedge of polygon vertex V,
|
||||
@@ -142,7 +118,7 @@ bool lineSegmentIntersectsPolygon(const matrix::Vector2f &start, const matrix::V
|
||||
for (int i = 0; i < num_vertices; i++) {
|
||||
const int prev = (i == 0) ? num_vertices - 1 : i - 1;
|
||||
|
||||
if (segmentsIntersect(vertices[prev], vertices[i], start, end) == SegSegResult::Proper) {
|
||||
if (segmentsIntersect(vertices[prev], vertices[i], start, end)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,23 +126,16 @@ inline bool collinearBetween(const matrix::Vector2f &a,
|
||||
}
|
||||
|
||||
/**
|
||||
* Result of a 2D segment-segment intersection test. The caller decides which
|
||||
* variants count as "intersecting" for its purpose -- there is no baked-in
|
||||
* convention. Reference: O'Rourke, "Computational Geometry in C" (2nd ed.),
|
||||
* SegSegInt, section 1.5.
|
||||
* Test for a proper 2D segment-segment intersection: each segment strictly
|
||||
* straddles the other's supporting line, with no endpoint lying on the other
|
||||
* segment and no collinear overlap. Returns false for endpoint-touching,
|
||||
* collinear-overlapping, or disjoint segments.
|
||||
*
|
||||
* Reference: O'Rourke, "Computational Geometry in C" (2nd ed.), SegSegInt,
|
||||
* section 1.5.
|
||||
*/
|
||||
enum class SegSegResult {
|
||||
None, ///< segments are disjoint
|
||||
Proper, ///< strict interior crossing of both segments
|
||||
Touching, ///< exactly one endpoint of one segment lies on the other (interior or shared endpoint)
|
||||
CollinearOverlap, ///< segments are collinear and share more than a point
|
||||
};
|
||||
|
||||
/**
|
||||
* Classify the intersection of segment ab with segment cd. See SegSegResult.
|
||||
*/
|
||||
SegSegResult segmentsIntersect(const matrix::Vector2f &a, const matrix::Vector2f &b,
|
||||
const matrix::Vector2f &c, const matrix::Vector2f &d);
|
||||
bool segmentsIntersect(const matrix::Vector2f &a, const matrix::Vector2f &b,
|
||||
const matrix::Vector2f &c, const matrix::Vector2f &d);
|
||||
|
||||
/**
|
||||
* Check if a line segment and a polygon have non-empty intersection.
|
||||
|
||||
Reference in New Issue
Block a user