Skip to content

Commit

Permalink
#474 ShadeTool - Fix Entity height calculation (#475)
Browse files Browse the repository at this point in the history
* #474 ShadeTool- Fix Entity height calculation

* #474 Remove comment of bad calculation line
  • Loading branch information
tariqksoliman authored Dec 14, 2023
1 parent b864a03 commit 5f3d031
Show file tree
Hide file tree
Showing 13 changed files with 499 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from math import sqrt
from math import tan

def distance_between_points(p1, p2, unit='meters', haversine=True, vincenty=False):
def distance_between_points(p1, p2, unit='meters', radius=None, haversine=True, vincenty=False):
""" This function computes the distance between two points in the unit given in the unit parameter. It will
calculate the distance using the haversine unless the user specifies haversine to be False. Then law of cosines
will be used
Expand All @@ -26,6 +26,8 @@ def distance_between_points(p1, p2, unit='meters', haversine=True, vincenty=Fals
lon2, lat2 = _point_to_radians(_error_check_point(p2))
r_earth = getattr(radius_earth, unit, 'meters')

if radius is not None:
r_earth = radius

if vincenty: # from https://nathanrooy.github.io/posts/2016-12-18/vincenty-formula-with-python/

Expand Down
28 changes: 28 additions & 0 deletions private/api/spice/great_circle_calculator/__conversion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
from ._constants import *
from .__error_checking import _error_check_point


def _degrees_to_radians(degrees):
""" Converts the degrees into radians
:param degrees: decimal degrees
:return: radians
"""
return pi * degrees / 180


def _radians_to_degrees(radians):
""" Converts the radians into degrees
:param radians: decimal degrees
:return: radians
"""
return 180 * radians / pi


def _point_to_radians(point):
point = _error_check_point(point)
return (_degrees_to_radians(point[0]), _degrees_to_radians(point[1]))


def _point_to_degrees(point):
return (_radians_to_degrees(point[0]), _radians_to_degrees(point[1]))
Binary file not shown.
18 changes: 18 additions & 0 deletions private/api/spice/great_circle_calculator/__error_checking.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
def _error_check_point(point, correct_point=True):
if len(point) != 2:
print("Point", str(point), "is incorrect length!")
return False
lon, lat = float(point[0]), float(point[1])
if -90 <= lat <= 90 and -180 <= lon <= 180: # Point makes sense
return (lon, lat)
# The point is (probably!) reversed
elif -90 <= lon <= 90 and -180 <= lat <= 180:
print("Point", str(point), "is probably reversed!")
if correct_point:
point_corrected = (lat, lon)
return point_corrected
return False
else:
print("Point", str(point), "Cannot be interpreted!")
return False
Binary file not shown.
2 changes: 2 additions & 0 deletions private/api/spice/great_circle_calculator/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
name = "great_circle_calculator"
Binary file not shown.
59 changes: 59 additions & 0 deletions private/api/spice/great_circle_calculator/_constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# -*- coding: utf-8 -*-
import math
from collections import namedtuple

pi = math.pi
# FAI Sphere
radius_earth_meters = 6371000
# Google Earth Sphere Radius
# radius_earth_meters = 6378137
eligible_units = ['meters', 'kilometers',
'miles', 'feet', 'yards', 'nautical_miles']
Units = namedtuple('Units', field_names=eligible_units)
radius_earth = Units(
meters=radius_earth_meters,
kilometers=radius_earth_meters / 1000,
miles=radius_earth_meters / 1609.344,
feet=radius_earth_meters * 3.28084,
nautical_miles=radius_earth_meters / 1852,
yards=radius_earth_meters * 1.09361
)


#
# The following functions are redefined and passed to the math.* function because it is sometimes cumbersome to go
# math.* for all these functions. Basically they are redefined here to make my life easier.
#

def sin(x):
return math.sin(x)


def cos(x):
return math.cos(x)


def asin(x):
x = _test_domain(x)
return math.asin(x)


def acos(x):
x = _test_domain(x)
return math.acos(x)


def atan2(y, x):
return math.atan2(y, x)


def sqrt(x):
return math.sqrt(x)


def _test_domain(x):
if x > 1:
return 1
if x < -1:
return -1
return x
Binary file not shown.
202 changes: 202 additions & 0 deletions private/api/spice/great_circle_calculator/compass.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
# -*- coding: utf-8 -*-
# This collection of classes just let me call something like compass.east to get 90 degrees.

from collections import namedtuple


class CompassSimple:
""" A class to use one of the 32 compass points inplace of degrees. This was made so I could just call
compass.east to get 90 degrees.
"""
north = N = 0
north_by_east = NbE = 11.25
north_northeast = NNE = 22.5
northeast_by_north = NEbN = 33.75
northeast = NE = 45
northeast_by_east = NEbE = 56.25
east_northeast = ENE = 67.5
east_by_north = EbN = 78.75
east = E = 90
east_by_south = EbS = 101.25
east_southeast = ESE = 112.5
southeast_by_east = SEbE = 123.75
southeast = SE = 135
southeast_by_south = SEbS = 146.25
south_southeast = SSE = 157.5
south_by_east = SbE = 168.75
south = S = 180
south_by_west = SbW = 191.25
south_southwest = SSW = 202.5
southwest_by_south = SWbS = 213.75
southwest = SW = 225
southwest_by_west = SWbW = 236.25
west_southwest = WSW = 247.5
west_by_south = WbS = 258.75
west = W = 270
west_by_north = WbN = 281.25
west_northwest = WNW = 292.5
northwest_by_west = NWbW = 303.75
northwest = NW = 315
northwest_by_north = NWbN = 326.25
north_northwest = NNW = 337.5
north_by_west = NbW = 348.75


class CompassComplex:
""" This class contains more information then the CompassSimple class.
Recommended to use import CompassComplex as compass.
"""
CompassPoint = namedtuple('CompassPoint', [
'Point', 'Abbr', 'WindPoint', 'Minimum', 'Direction', 'Maximum'])
compass = dict()
compass['north'] = compass['N'] = north = N = CompassPoint(
'north', 'N', 'Tramontana', 354.375, 0.000, 5.625)
compass['north by east'] = compass['NbE'] = north_by_east = NbE = CompassPoint('north by east', 'NbE',
'Quarto di Tramontana verso Greco',
5.625, 11.250, 16.875)
compass['north-northeast'] = compass['NNE'] = north_northeast = NNE = CompassPoint('north-northeast', 'NNE',
'Greco-Tramontana', 16.875,
22.500, 28.125)
compass['northeast by north'] = compass['NEbN'] = northeast_by_north = NEbN = CompassPoint('northeast by north',
'NEbN',
'Quarto di Greco verso Tramontana',
28.125, 33.750, 39.375)
compass['northeast'] = compass['NE'] = northeast = NE = CompassPoint('northeast', 'NE', 'Greco', 39.375, 45.000,
50.625)
compass['northeast by east'] = compass['NEbE'] = northeast_by_east = NEbE = CompassPoint('northeast by east',
'NEbE',
'Quarto di Greco verso Levante',
50.625, 56.250, 61.875)
compass['east-northeast'] = compass['ENE'] = east_northeast = ENE = CompassPoint('east-northeast', 'ENE',
'Greco-Levante', 61.875, 67.500,
73.125)
compass['east by north'] = compass['EbN'] = east_by_north = EbN = CompassPoint('east by north', 'EbN',
'Quarto di Levante verso Greco',
73.125, 78.750, 84.375)
compass['east'] = compass['E'] = east = E = CompassPoint(
'east', 'E', 'Levante', 84.375, 90.000, 95.625)
compass['east by south'] = compass['EbS'] = east_by_south = EbS = CompassPoint('east by south', 'EbS',
'Quarto di Levante verso Scirocco',
95.625, 101.250, 106.875)
compass['east-southeast'] = compass['ESE'] = east_southeast = ESE = CompassPoint('east-southeast', 'ESE',
'Levante-Scirocco', 106.875,
112.500, 118.125)
compass['southeast by east'] = compass['SEbE'] = southeast_by_east = SEbE = CompassPoint('southeast by east',
'SEbE',
'Quarto di Scirocco verso Levante',
118.125, 123.750, 129.375)
compass['southeast'] = compass['SE'] = southeast = SE = CompassPoint('southeast', 'SE', 'Scirocco', 129.375,
135.000, 140.625)
compass['southeast by south'] = compass['SEbS'] = southeast_by_south = SEbS = CompassPoint('southeast by south',
'SEbS',
'Quarto di Scirocco verso Ostro',
140.625, 146.250,
151.875)
compass['south-southeast'] = compass['SSE'] = south_southeast = SSE = CompassPoint('south-southeast', 'SSE',
'Ostro-Scirocco', 151.875,
157.500, 163.125)
compass['south by east'] = compass['SbE'] = south_by_east = SbE = CompassPoint('south by east', 'SbE',
'Quarto di Ostro verso Scirocco',
163.125, 168.750, 174.375)
compass['south'] = compass['S'] = south = S = CompassPoint(
'south', 'S', 'Ostro', 174.375, 180.000, 185.625)
compass['south by west'] = compass['SbW'] = south_by_west = SbW = CompassPoint('south by west', 'SbW',
'Quarto di Ostro verso Libeccio',
185.625, 191.250, 196.875)
compass['south-southwest'] = compass['SSW'] = south_southwest = SSW = CompassPoint('south-southwest', 'SSW',
'Ostro-Libeccio', 196.875,
202.500, 208.125)
compass['southwest by south'] = compass['SWbS'] = southwest_by_south = SWbS = CompassPoint('southwest by south',
'SWbS',
'Quarto di Libeccio verso Ostro',
208.125, 213.750,
219.375)
compass['southwest'] = compass['SW'] = southwest = SW = CompassPoint('southwest', 'SW', 'Libeccio', 219.375,
225.000, 230.625)
compass['southwest by west'] = compass['SWbW'] = southwest_by_west = SWbW = CompassPoint('southwest by west',
'SWbW',
'Quarto di Libeccio verso Ponente',
230.625, 236.250, 241.875)
compass['west-southwest'] = compass['WSW'] = west_southwest = WSW = CompassPoint('west-southwest', 'WSW',
'Ponente-Libeccio', 241.875,
247.500, 253.125)
compass['west by south'] = compass['WbS'] = west_by_south = WbS = CompassPoint('west by south', 'WbS',
'Quarto di Ponente verso Libeccio',
253.125, 258.750, 264.375)
compass['west'] = compass['W'] = west = W = CompassPoint(
'west', 'W', 'Ponente', 264.375, 270.000, 275.625)
compass['west by north'] = compass['WbN'] = west_by_north = WbN = CompassPoint('west by north', 'WbN',
'Quarto di Ponente verso Maestro',
275.625, 281.250, 286.875)
compass['west-northwest'] = compass['WNW'] = west_northwest = WNW = CompassPoint('west-northwest', 'WNW',
'Maestro-Ponente', 286.875,
292.500, 298.125)
compass['northwest by west'] = compass['NWbW'] = northwest_by_west = NWbW = CompassPoint('northwest by west',
'NWbW',
'Quarto di Maestro verso Ponente',
298.125, 303.750, 309.375)
compass['northwest'] = compass['NW'] = northwest = NW = CompassPoint('northwest', 'NW', 'Maestro', 309.375, 315.000,
320.625)
compass['northwest by north'] = compass['NWbN'] = northwest_by_north = NWbN = CompassPoint('northwest by north',
'NWbN',
'Quarto di Maestro verso Tramontana',
320.625, 326.250,
331.875)
compass['north-northwest'] = compass['NNW'] = north_northwest = NNW = CompassPoint('north-northwest', 'NNW',
'Maestro-Tramontana', 331.875,
337.500, 343.125)
compass['north by west'] = compass['NbW'] = north_by_west = NbW = CompassPoint('north by west', 'NbW',
'Quarto di Tramontana verso Maestro',
343.125, 348.750, 354.375)

full_name = ['north', 'north by east', 'north-northeast', 'northeast by north', 'northeast', 'northeast by east',
'east-northeast', 'east by north', 'east', 'east by south', 'east-southeast', 'southeast by east',
'southeast', 'southeast by south', 'south-southeast', 'south by east', 'south', 'south by west',
'south-southwest', 'southwest by south', 'southwest', 'southwest by west', 'west-southwest',
'west by south', 'west', 'west by north', 'west-northwest', 'northwest by west', 'northwest',
'northwest by north', 'north-northwest', 'north by west']
abbr = ['N', 'NbE', 'NNE', 'NEbN', 'NE', 'NEbE', 'ENE', 'EbN', 'E', 'EbS', 'ESE', 'SEbE', 'SE', 'SEbS', 'SSE',
'SbE', 'S', 'SbW', 'SSW', 'SWbS', 'SW', 'SWbW', 'WSW', 'WbS', 'W', 'WbN', 'WNW', 'NWbW', 'NW', 'NWbN',
'NNW', 'NbW']

def __init__(self):
"""
Initializer for the Compass Class
"""
pass

def get_point(self, heading):
return self._get_dir_name(heading, self.full_name)

def get_abbr(self, heading):
return self._get_dir_name(heading, self.abbr)

def _get_dir_name(self, heading, type):
"""
General case for finding the direction
:param heading:
:param type:
:return:
"""
heading = heading % 360
for point in type:
if self.compass[point].Direction == 0:
if self.compass[point].Minimum <= heading <= 360.0 or 0.0 <= heading < self.compass[point].Maximum:
return point
elif self.compass[point].Minimum <= heading < self.compass[point].Maximum:
return point


if __name__ == '__main__':
import math
print(CompassComplex.get_point(CompassComplex(), 200))
print(CompassComplex.get_point(0))
print(CompassComplex.get_point(360))
print(CompassComplex.get_point(100))
print(CompassComplex.get_point(2 * math.pi))
print(CompassComplex.get_point(-15))
print(CompassComplex.get_point(-360))
print(CompassComplex.get_point(400))
print(CompassComplex.get_point(-600))
print(CompassComplex.N)
print(CompassComplex.E.Direction)
Loading

0 comments on commit 5f3d031

Please sign in to comment.