Skip to content

Instantly share code, notes, and snippets.

@george-silva
Created December 24, 2013 16:01
Show Gist options
  • Select an option

  • Save george-silva/8115095 to your computer and use it in GitHub Desktop.

Select an option

Save george-silva/8115095 to your computer and use it in GitHub Desktop.
Formula calculo azimute.
class CalculadoraAzimuteDistancia(object):
"""
Calcula o azimute entre dois pontos
"""
def distancia(self, p1, p2, h1=0, h2=0):
"""
Calcula p1 distância entre dois pontos p1 e p2
"""
di = math.pow((math.pow(p2.x - p1.x, 2) + math.pow(p2.y - p1.y, 2) + math.pow(p2.z - p1.z, 2)), 0.5)
dn = h2 - h1
dh = abs(di * di - dn * dn) ** 0.5
return dh
def azimute_reto(self, p1, p2, casas=6):
# guarda para nao entramos em loop infinito.
if casas > 15:
return None
delta_x = round(p2.x - p1.x, casas)
delta_y = round(p2.y - p1.y, casas)
if delta_x == 0 and delta_y == 0:
casas += 1
return self.azimute_reto(p1, p2, casas=casas)
if delta_x == 0 and delta_y > 0:
return 0
if delta_x > 0 and delta_y == 0:
return 90
if delta_x == 0 and delta_y < 0:
return 180
if delta_x < 0 and delta_y == 0:
return 270
return None
def azimute_puissant(self, p1, p2):
"""
Calcula azimute puissant
"""
f = 0.00335281068118
inv_f = 298.257222101
e2 = 0.00669438002290
a = 6378137
b = 6356752.314140
seno_1segundo = 0.00000484813681108
lat_media = (radians(p1.y) + radians(p2.y)) / 2
seno_lat_media = math.sin(lat_media)
cos_lat_media = math.cos(lat_media)
pow_seno_20 = math.pow(seno_lat_media, 2)
nm = a / (math.pow(1 - (e2 * pow_seno_20), 0.5))
delta_lat = (p2.y - p1.y) * 3600
delta_lon = (p2.x - p1.x) * 3600
mm = (a * (1 - e2)) / math.pow(1 - (e2 * pow_seno_20), 1.5)
bm = 1 / (mm * seno_1segundo)
x = delta_lon * cos_lat_media * nm * seno_1segundo
y = delta_lat * cos(radians(delta_lon / 7200)) * mm * seno_1segundo + 0.0000000001
F = (1 / 12) * seno_lat_media * cos_lat_media * cos_lat_media * seno_1segundo * seno_1segundo
gamma = (delta_lon * seno_lat_media * (1 / cos(radians(delta_lat / 7200))) + (
F * delta_lon * delta_lon * delta_lon))
if x < 0:
sinal_x = -1
elif x == 0:
sinal_x = 0
else:
sinal_x = 1
if y < 0:
sinal_y = -1
elif y == 0:
sinal_y = 0
else:
sinal_y = 1
if sinal_y == 0:
if delta_lat == 0 and delta_lon > 0:
return 90
# oeste
if delta_lat == 0 and delta_lon < 0:
return 270
if delta_lon > 0 and delta_lat > 0:
return math.degrees(math.atan(delta_lon / delta_lat))
if (delta_lon > 0 > delta_lat) or (delta_lon < 0 and delta_lat < 0):
return math.degrees(math.atan(delta_lon / delta_lat)) + 180
if delta_lon < 0 < delta_lat:
return math.degrees(math.atan(delta_lon / delta_lat)) + 360
azimute = 180 * (1 - (0.5 * sinal_x) - (0.5 * sinal_x * sinal_y)) + (math.degrees(math.atan(x / y)) - (
gamma / 7200))
quase_reto = self.quase_reto(azimute)
if quase_reto is not None:
return quase_reto
return azimute
def quase_reto(self, azimute):
if self.assertAlmostEqual(360, azimute, delta=0.2):
return 360
if self.assertAlmostEqual(0, azimute, delta=0.2):
return 0
if self.assertAlmostEqual(90, azimute, delta=0.2):
return 90
if self.assertAlmostEqual(180, azimute, delta=0.2):
return 180
if self.assertAlmostEqual(270, azimute, delta=0.2):
return 270
return None
def assertAlmostEqual(self, first, second, places=None, delta=None):
"""Roubado do unittest"""
if first == second:
# shortcut
return True
if delta is not None and places is not None:
raise TypeError("specify delta or places not both")
if delta is not None:
if abs(first - second) <= delta:
return True
else:
if places is None:
places = 7
if round(abs(second - first), places) == 0:
return True
return False
def azimute_aritmetico(self, a, b):
pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment