Coverage for pyguymer3/intersection.py: 66%

29 statements  

« prev     ^ index     » next       coverage.py v7.9.2, created at 2025-07-08 18:47 +0000

1#!/usr/bin/env python3 

2 

3# Define function ... 

4def intersection( 

5 p1, 

6 p2, 

7 p3, 

8 p4, 

9 /, 

10): 

11 """ 

12 This function finds the intersection of two line segments (defined by four 

13 points). 

14 """ 

15 

16 # Import special modules ... 

17 try: 

18 import numpy 

19 except: 

20 raise Exception("\"numpy\" is not installed; run \"pip install --user numpy\"") from None 

21 

22 # Catch simple misses ... 

23 if max(p1[0], p2[0]) < min(p3[0], p4[0]): 

24 # NOTE: line segment #1 is left of line segment #2. 

25 return False 

26 if min(p1[0], p2[0]) > max(p3[0], p4[0]): 

27 # NOTE: line segment #1 is right of line segment #2. 

28 return False 

29 if max(p1[1], p2[1]) < min(p3[1], p4[1]): 

30 # NOTE: line segment #1 is below line segment #2. 

31 return False 

32 if min(p1[1], p2[1]) > max(p3[1], p4[1]): 

33 # NOTE: line segment #1 is above line segment #2. 

34 return False 

35 

36 # Find gradients of the two lines ... 

37 m1 = (p2[1] - p1[1]) / (p2[0] - p1[0]) 

38 m2 = (p4[1] - p3[1]) / (p4[0] - p3[0]) 

39 

40 # Find intercepts of the two lines ... 

41 c1 = p1[1] - m1 * p1[0] 

42 c2 = p3[1] - m2 * p3[0] 

43 

44 # Assemble matrices ... 

45 a = numpy.array([[-m1, 1.0], [-m2, 1.0]]) 

46 b = numpy.array([c1, c2]) 

47 

48 # Solve two linear equations ... 

49 p5 = numpy.linalg.solve(a, b) 

50 

51 # Catch complex misses ... 

52 if not min(p1[0], p2[0]) <= p5[0] <= max(p1[0], p2[0]): 

53 # NOTE: intersection is either left or right of line segment #1. 

54 return False 

55 if not min(p1[1], p2[1]) <= p5[1] <= max(p1[1], p2[1]): 

56 # NOTE: intersection is either above or below line segment #1. 

57 return False 

58 if not min(p3[0], p4[0]) <= p5[0] <= max(p3[0], p4[0]): 

59 # NOTE: intersection is either left or right of line segment #2. 

60 return False 

61 if not min(p3[1], p4[1]) <= p5[1] <= max(p3[1], p4[1]): 

62 # NOTE: intersection is either above or below line segment #2. 

63 return False 

64 

65 # Return answer ... 

66 return p5