Skip to content

Commit 8079fd4

Browse files
authored
segmentIntersectionOrder: shared point case (#4794)
1 parent 953ee8f commit 8079fd4

File tree

3 files changed

+35
-0
lines changed

3 files changed

+35
-0
lines changed

source/MRMesh/MRPrecisePredicates2.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,28 @@ bool segmentIntersectionOrder( const std::array<PreciseVertCoords2, 6> & vs )
274274
// s=01, sa=23, sb=45
275275
assert( doSegmentSegmentIntersect( { vs[0], vs[1], vs[2], vs[3] } ) );
276276
assert( doSegmentSegmentIntersect( { vs[0], vs[1], vs[4], vs[5] } ) );
277+
278+
// if sa and sb have a shared point
279+
auto sa0 = vs[2];
280+
auto sa1 = vs[3];
281+
auto sb0 = vs[4];
282+
auto sb1 = vs[5];
283+
if ( sa1.id == sb0.id )
284+
std::swap( sa0, sa1 );
285+
else if ( sa0.id == sb1.id )
286+
std::swap( sb0, sb1 );
287+
else if ( sa1.id == sb1.id )
288+
{
289+
std::swap( sa0, sa1 );
290+
std::swap( sb0, sb1 );
291+
}
292+
if ( sa0.id == sb0.id )
293+
{
294+
assert( sa0.pt == sb0.pt );
295+
assert( sa1.id != sb1.id );
296+
return ccw( { sa0, sa1, sb1 } ) == ccw( { sa0, sa1, vs[1] } );
297+
}
298+
277299
const auto ds = getPointDegrees( vs );
278300

279301
// res = ( ccw(sa,s[0])*ccw(sb,ds[1]) - ccw(sb,s[0])*ccw(sa,ds[1]) ) /

source/MRMesh/MRPrecisePredicates2.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ struct CoordinateConverters2
7979
/// given line segment s=01 and two other segments sa=23, sb=45 known to intersect it, finds the order of intersection using precise predicates:
8080
/// true: s[0], s ^ sa, s ^ sb, s[1]
8181
/// false: s[0], s ^ sb, s ^ sa, s[1]
82+
/// segments sa and sb can have at most one shared point, all other points must be unique
8283
[[nodiscard]] MRMESH_API bool segmentIntersectionOrder( const std::array<PreciseVertCoords2, 6> & vs );
8384

8485
/// finds intersection precise, using high precision int inside

source/MRTest/MRPrecisePredicatesTests.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ TEST( MRMesh, PrecisePredicates2More )
113113
// intersection of 45 and 03 is closer to 4 than intersection of 45 and 12
114114
EXPECT_TRUE( segmentIntersectionOrder( { vs[4], vs[5], vs[0], vs[3], vs[1], vs[2] } ) );
115115
EXPECT_FALSE( segmentIntersectionOrder( { vs[5], vs[4], vs[0], vs[3], vs[1], vs[2] } ) );
116+
117+
// intersection of 45 and 03 is closer to 4 than intersection of 45 and 02
118+
EXPECT_TRUE( segmentIntersectionOrder( { vs[4], vs[5], vs[0], vs[3], vs[0], vs[2] } ) );
119+
EXPECT_FALSE( segmentIntersectionOrder( { vs[4], vs[5], vs[0], vs[2], vs[0], vs[3] } ) );
116120
}
117121

118122
TEST( MRMesh, PrecisePredicates2FullDegen )
@@ -221,6 +225,14 @@ TEST( MRMesh, PreciseSegmentIntersectionOrder2 )
221225
EXPECT_FALSE( segmentIntersectionOrder( { vs[0], vs[1], vs[4], vs[5], vs[3], vs[2] } ) );
222226
EXPECT_FALSE( segmentIntersectionOrder( { vs[0], vs[1], vs[5], vs[4], vs[3], vs[2] } ) );
223227
EXPECT_TRUE( segmentIntersectionOrder( { vs[1], vs[0], vs[5], vs[4], vs[3], vs[2] } ) );
228+
229+
// shared point in sa and sb
230+
EXPECT_TRUE( segmentIntersectionOrder( { vs[0], vs[1], vs[2], vs[3], vs[2], vs[5] } ) );
231+
EXPECT_TRUE( segmentIntersectionOrder( { vs[0], vs[1], vs[3], vs[2], vs[2], vs[5] } ) );
232+
EXPECT_TRUE( segmentIntersectionOrder( { vs[0], vs[1], vs[2], vs[3], vs[5], vs[2] } ) );
233+
EXPECT_FALSE( segmentIntersectionOrder( { vs[0], vs[1], vs[4], vs[5], vs[2], vs[5] } ) );
234+
EXPECT_FALSE( segmentIntersectionOrder( { vs[0], vs[1], vs[4], vs[5], vs[5], vs[2] } ) );
235+
EXPECT_FALSE( segmentIntersectionOrder( { vs[0], vs[1], vs[5], vs[4], vs[5], vs[2] } ) );
224236
}
225237

226238
TEST( MRMesh, PrecisePredicates3 )

0 commit comments

Comments
 (0)