Перевод координат: реализация
Соберём формулы сферической тригонометрии в работающую функцию перевода RA/Dec в высоту/азимут.
Часовой угол (H) — угол между меридианом наблюдателя и объектом, равный звёздному времени минус RA. Он связывает «паспортные» координаты с локальным небом.
Формулы перевода
Чтобы перевести экваториальные координаты (склонение $\delta$, часовой угол $H$) в горизонтальные (высота $h$, азимут $A$) на широте $\varphi$, используют две формулы сферической тригонометрии:
$$\sin h = \sin\delta \sin\varphi + \cos\delta \cos\varphi \cos H$$
$$\cos A = \frac{\sin\delta - \sin h \sin\varphi}{\cos h \cos\varphi}$$
Первая даёт высоту напрямую через $\arcsin$. Вторая даёт косинус азимута; чтобы снять неоднозначность арккосинуса (он не различает восток и запад), смотрят на знак $\sin H$: если объект на западной стороне ($\sin H \gt 0$), азимут берут как $360° - A$.
Реализация
import math
def eq_to_horiz(ha_deg, dec_deg, lat_deg):
"""Часовой угол и склонение -> (высота, азимут) в градусах."""
H = math.radians(ha_deg)
d = math.radians(dec_deg)
phi = math.radians(lat_deg)
sin_alt = math.sin(d) * math.sin(phi) + math.cos(d) * math.cos(phi) * math.cos(H)
alt = math.asin(sin_alt)
cos_A = (math.sin(d) - math.sin(alt) * math.sin(phi)) / (math.cos(alt) * math.cos(phi))
cos_A = max(-1.0, min(1.0, cos_A)) # защита от ошибок округления
A = math.acos(cos_A)
if math.sin(H) > 0:
A = 2 * math.pi - A
return math.degrees(alt), math.degrees(A)
# Объект: часовой угол 15°, склонение 20°, широта наблюдателя 55°
alt, az = eq_to_horiz(15.0, 20.0, 55.0)
print("Высота:", round(alt, 2), "град")
print("Азимут:", round(az, 2), "град")Вывод:
Высота: 53.21 град Азимут: 203.96 град
Как работает под капотом
Эти формулы — частный случай сферической теоремы косинусов, применённой к «астрономическому треугольнику»: его вершины — полюс мира, зенит и объект. Стороны треугольника — это $90° - \delta$, $90° - \varphi$ и $90° - h$, а углы — часовой угол $H$ и азимут $A$. Решая этот треугольник, мы и получаем перевод. Строчка cos_A = max(-1.0, min(1.0, cos_A)) — практический приём: из-за ошибок округления косинус может получиться чуть больше $1$ или меньше $-1$, и тогда math.acos упадёт. Зажимаем значение в допустимый диапазон.
Частые ошибки
- Подставлять градусы в
math.sinбез перевода в радианы. - Игнорировать неоднозначность азимута — без проверки $\sin H$ восток перепутается с западом.
- Не защитить
acosот значений за пределами $[-1, 1]$ — программа упадёт на крайних случаях.
Итог
- Перевод координат — это решение астрономического треугольника через $\sin$/$\cos$.
- Высота берётся через $\arcsin$, азимут — через $\arccos$ плюс проверка знака $\sin H$.
- Зажимайте аргумент
acosв $[-1, 1]$, чтобы не словить ошибку округления.