Coverage for pyguymer3/geo/find_point_on_great_circle.py: 95%

22 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 find_point_on_great_circle( 

5 frac, 

6 lon1_deg, 

7 lat1_deg, 

8 lon2_deg, 

9 lat2_deg, 

10 /, 

11): 

12 """Calculate an arbitrary point on the great circle that connects two 

13 coordinates. 

14 

15 This function reads in two coordinates (in degrees) on the surface of the 

16 Earth and calculates an arbitrary point on the great circle that connects 

17 them, correctly handling crossing over the anti-meridian (should it occur). 

18 

19 Parameters 

20 ---------- 

21 frac : float 

22 the location of the arbitrary point on the great circle from the first 

23 coordinate to the second coordinate 

24 lon1 : float 

25 the longitude of the first coordinate (in degrees) 

26 lat1 : float 

27 the latitude of the first coordinate (in degrees) 

28 lon2 : float 

29 the longitude of the second coordinate (in degrees) 

30 lat2 : float 

31 the latitude of the second coordinate (in degrees) 

32 

33 Returns 

34 ------- 

35 lon3 : float 

36 the longitude of the arbitrary point on the great circle (in degrees) 

37 lat3 : float 

38 the latitude of the arbitrary point on the great circle (in degrees) 

39 

40 Notes 

41 ----- 

42 Copyright 2017 Thomas Guymer [1]_ 

43 

44 References 

45 ---------- 

46 .. [1] PyGuymer3, https://github.com/Guymer/PyGuymer3 

47 """ 

48 

49 # Import standard modules ... 

50 import math 

51 

52 # Import sub-functions ... 

53 from .calc_angle_between_two_locs import calc_angle_between_two_locs 

54 

55 # ************************************************************************** 

56 

57 # Check arguments ... 

58 if lon1_deg == lon2_deg and lat1_deg == lat2_deg: 

59 return lon1_deg, lat1_deg 

60 if frac <= 0.0: 

61 return lon1_deg, lat1_deg 

62 if frac >= 1.0: 

63 return lon2_deg, lat2_deg 

64 

65 # Convert to radians ... 

66 lon1_rad = math.radians(lon1_deg) # [rad] 

67 lat1_rad = math.radians(lat1_deg) # [rad] 

68 lon2_rad = math.radians(lon2_deg) # [rad] 

69 lat2_rad = math.radians(lat2_deg) # [rad] 

70 

71 # Calculate point ... 

72 rad = math.radians(calc_angle_between_two_locs(lon1_deg, lat1_deg, lon2_deg, lat2_deg)) # [rad] 

73 a = math.sin((1.0 - frac) * rad) / math.sin(rad) 

74 b = math.sin(frac * rad) / math.sin(rad) 

75 x = a * math.cos(lat1_rad) * math.cos(lon1_rad) + b * math.cos(lat2_rad) * math.cos(lon2_rad) 

76 y = a * math.cos(lat1_rad) * math.sin(lon1_rad) + b * math.cos(lat2_rad) * math.sin(lon2_rad) 

77 z = a * math.sin(lat1_rad) + b * math.sin(lat2_rad) 

78 lat3_rad = math.atan2( 

79 z, 

80 math.hypot( 

81 x, 

82 y 

83 ) 

84 ) # [rad] 

85 lon3_rad = math.atan2( 

86 y, 

87 x 

88 ) # [rad] 

89 

90 # Return point ... 

91 return math.degrees(lon3_rad), math.degrees(lat3_rad)