@@ -1521,6 +1521,32 @@ impl Segment2d {
1521
1521
let t = projection_scaled / length_squared;
1522
1522
self . vertices [ 0 ] + t * segment_vector
1523
1523
}
1524
+
1525
+ /// Returns the point of intersection between this [`Segment2d`] and another, if it exists.
1526
+ #[ inline( always) ]
1527
+ pub fn intersect ( & self , other : Self ) -> Option < Vec2 > {
1528
+ let p = self . point1 ( ) ;
1529
+ let q = other. point1 ( ) ;
1530
+ let r = self . scaled_direction ( ) ;
1531
+ let s = other. scaled_direction ( ) ;
1532
+
1533
+ let r_cross_s = r. perp_dot ( s) ;
1534
+ let q_minus_p = q - p;
1535
+
1536
+ if r_cross_s != 0.0 {
1537
+ let t = q_minus_p. perp_dot ( s / r_cross_s) ;
1538
+ let u = q_minus_p. perp_dot ( r / r_cross_s) ;
1539
+
1540
+ let t_in_range = ( 0.0 ..=1.0 ) . contains ( & t) ;
1541
+ let u_in_range = ( 0.0 ..=1.0 ) . contains ( & u) ;
1542
+
1543
+ if t_in_range && u_in_range {
1544
+ return Some ( p + t * r) ;
1545
+ }
1546
+ }
1547
+
1548
+ None
1549
+ }
1524
1550
}
1525
1551
1526
1552
impl From < [ Vec2 ; 2 ] > for Segment2d {
@@ -2375,6 +2401,29 @@ mod tests {
2375
2401
}
2376
2402
}
2377
2403
2404
+ #[ test]
2405
+ fn segment_intersect ( ) {
2406
+ let isec = Segment2d :: new ( Vec2 :: new ( 0.0 , 0.0 ) , Vec2 :: new ( 2.0 , 2.0 ) )
2407
+ . intersect ( Segment2d :: new ( Vec2 :: new ( 0.0 , 2.0 ) , Vec2 :: new ( 2.0 , 0.0 ) ) ) ;
2408
+ assert_eq ! ( isec, Some ( Vec2 :: new( 1.0 , 1.0 ) ) ) ;
2409
+
2410
+ let isec = Segment2d :: new ( Vec2 :: new ( 0.0 , 0.0 ) , Vec2 :: new ( 2.0 , 0.0 ) )
2411
+ . intersect ( Segment2d :: new ( Vec2 :: new ( 0.0 , 1.0 ) , Vec2 :: new ( 2.0 , 1.0 ) ) ) ;
2412
+ assert_eq ! ( isec, None ) ;
2413
+
2414
+ let isec = Segment2d :: new ( Vec2 :: new ( 0.0 , 0.0 ) , Vec2 :: new ( 1.0 , 1.0 ) )
2415
+ . intersect ( Segment2d :: new ( Vec2 :: new ( 2.0 , 2.0 ) , Vec2 :: new ( 3.0 , 3.0 ) ) ) ;
2416
+ assert_eq ! ( isec, None ) ;
2417
+
2418
+ let isec = Segment2d :: new ( Vec2 :: new ( 0.0 , 0.0 ) , Vec2 :: new ( 1.0 , 1.0 ) )
2419
+ . intersect ( Segment2d :: new ( Vec2 :: new ( 1.0 , 1.0 ) , Vec2 :: new ( 2.0 , 0.0 ) ) ) ;
2420
+ assert_eq ! ( isec, Some ( Vec2 :: new( 1.0 , 1.0 ) ) ) ;
2421
+
2422
+ let isec = Segment2d :: new ( Vec2 :: new ( 0.0 , 0.0 ) , Vec2 :: new ( 1.0 , 0.0 ) )
2423
+ . intersect ( Segment2d :: new ( Vec2 :: new ( 2.0 , 0.0 ) , Vec2 :: new ( 3.0 , 0.0 ) ) ) ;
2424
+ assert_eq ! ( isec, None ) ;
2425
+ }
2426
+
2378
2427
#[ test]
2379
2428
fn circle_math ( ) {
2380
2429
let circle = Circle { radius : 3.0 } ;
0 commit comments