Skip to content

Instantly share code, notes, and snippets.

@zhustec
Last active May 3, 2020 05:36
Show Gist options
  • Select an option

  • Save zhustec/1b2292539f8fd4f96f718b55be2c3869 to your computer and use it in GitHub Desktop.

Select an option

Save zhustec/1b2292539f8fd4f96f718b55be2c3869 to your computer and use it in GitHub Desktop.
Calculate spherical distance and azimuth of waypoints
#!/usr/bin/env python3
import numpy as np
def calc_params(points):
"""Calculate some shared intermediate parameters
"""
points = np.array(points)
curr_points, next_points = points[:-1, :], points[1:, :]
Ξ” = next_points - curr_points
Ξ”πœ‘, Ξ”πœ† = Ξ”[:, 0], Ξ”[:, 1]
πœ‘1, πœ‘2 = curr_points[:, 0], next_points[:, 0]
sinπœ‘1, cosπœ‘1 = np.sin(πœ‘1), np.cos(πœ‘1)
sinπœ‘2, cosπœ‘2 = np.sin(πœ‘2), np.cos(πœ‘2)
return Ξ”πœ‘, Ξ”πœ†, sinπœ‘1, cosπœ‘1, sinπœ‘2, cosπœ‘2
def calc_angle(points, *, decimals = 1, premable = True):
"""Calculate azimuth of waypoints
Parameters:
points: 2-dimentional array(N x 2), each line is a waypoint
decimals: Significant digits count of the result
premable: Add premable 0 to the first point
Returns:
Azimuth to next waypoint
"""
Ξ”πœ‘, Ξ”πœ†, sinπœ‘1, cosπœ‘1, sinπœ‘2, cosπœ‘2 = calc_params(points)
sinΞ”πœ†, cosΞ”πœ† = np.sin(Ξ”πœ†), np.cos(Ξ”πœ†)
πœƒ = np.arctan2(sinΞ”πœ† * cosπœ‘2, cosπœ‘1 * sinπœ‘2 - sinπœ‘1 * cosπœ‘2 * cosΞ”πœ†) * 180 / np.pi
πœƒ = np.where(πœƒ < 0, πœƒ + 360, πœƒ)
return np.around(np.insert(πœƒ, 0, 0) if premable else πœƒ, decimals = decimals)
def calc_distance(points, *, decimals = 1, premable = True, radius = 6370):
"""Calculate spherical distance of waypoints
Parameters:
points: 2-dimentional array(N x 2), each line is a waypoint
decimals: Significant digits count of the result
premable: Add premable 0 to the first point
radius: Radius of pherical in kilometers
Returns:
Spherical distance to next waypoint in kilometers
"""
Ξ”πœ‘, Ξ”πœ†, sinπœ‘1, cosπœ‘1, sinπœ‘2, cosπœ‘2 = calc_params(points)
π‘Ž = np.sin(Ξ”πœ‘ / 2) ** 2 + cosπœ‘1 * cosπœ‘2 * np.sin(Ξ”πœ† / 2) ** 2
𝛿 = np.arctan2(np.sqrt(π‘Ž), np.sqrt(1 - π‘Ž)) * 2
𝑑 = 𝛿 * radius
return np.around(np.insert(𝑑, 0, 0) if premable else 𝑑, decimals = decimals)
def print_distance_and_azimuth(points):
points = np.array(points)
angle, distance = calc_angle(points).astype(str), calc_distance(points).astype(str)
centerize = lambda *strs, width = 14: [s.center(width) for s in strs]
print(*centerize('Waypoint', 'Distance', 'Azimuth'))
for index, point in enumerate(zip(distance, angle)):
print(*centerize(str(index + 1), point[0] + 'km', point[1] + 'Β°'), end = ' ')
print()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment