Last active
May 3, 2020 05:36
-
-
Save zhustec/1b2292539f8fd4f96f718b55be2c3869 to your computer and use it in GitHub Desktop.
Calculate spherical distance and azimuth of waypoints
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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