Узнайте, почему наивная проверка ретроградности планет даёт ложные срабатывания из-за перехода через 0° и как исправить это с помощью angularDelta. Практический пример на Python.
Если вы когда-нибудь писали код для астрономических расчётов, то наверняка сталкивались с задачей определения ретроградности планет. Наивная реализация — вычислить долготу в два момента времени и проверить знак разности — даёт сбой на переходе через 0° Овна. В этой статье я покажу, как избежать этой ошибки, и объясню, почему она важна не только для астрономии, но и для любого кода, работающего с углами.
Представьте, что вы вычисляете ретроградность как lon(t+step) - lon(t) < 0. Для Сатурна в апреле 1996 года реальные значения долготы:
λ(1996-04-07) = 359.95541°
λ(1996-04-09) = 0.19549°Сатурн движется прямо, приращение +0.24008°, но разность даёт −359.75992°. Детектор видит огромную отрицательную скорость и объявляет ретроградность. На самом деле планета просто пересекла 0° Овна — начало системы координат. Это не единичный случай: за 200 лет (1900–2100) для восьми планет таких ложных ретроградных периодов — 584, и каждый попадает на чей-то день рождения.
Проблема в том, что долготу нельзя вычитать как обычные числа. Нужно вычислить кратчайшую угловую разность, нормализованную в диапазон (−180, 180]. На Python это выглядит так:
def normalize_degrees(deg: float) -> float:
"""Нормализует угол в диапазон [0, 360)."""
d = (deg % 360 + 360) % 360
return 0 if d == 360 else d
def angular_delta(a: float, b: float) -> float:
"""Кратчайшая угловая разность a-b, в (-180, 180]."""
d = normalize_degrees(a - b)
return d - 360 if d > 180 else d
# Пример:
print(angular_delta(0.19549, 359.95541)) # +0.24008Теперь разность имеет правильный знак и величину. Для Сатурна в 1996 году детектор находит два реальных периода: 20 июля и 5 декабря, без ложных срабатываний.
Эта ошибка характерна для любых вычислений с циклическими величинами: долгота, азимут, фаза, цветовой тон, время суток. Если в вашем коде есть a - b, где a — угол, скорее всего, он где-то неверен. Всегда используйте angular_delta для разности углов.
Станция — момент, когда видимое движение планеты меняет знак. Для её поиска нужно найти корень функции скорости. Используем выборку долготы с шагом, зависящим от планеты, и бисекцию для уточнения:
def geocentric_ecliptic_longitude(body, date):
# Здесь вызов библиотеки astronomy-engine или аналога
# Возвращает видимую геоцентрическую долготу в градусах
pass
def velocity(ms, body, half_step_ms):
lon_plus = geocentric_ecliptic_longitude(body, ms + half_step_ms)
lon_minus = geocentric_ecliptic_longitude(body, ms - half_step_ms)
return angular_delta(lon_plus, lon_minus)
def find_station(body, start_ms, end_ms, step_ms, refine_ms=5000):
"""Бисекция для поиска станции между start и end."""
# Инициализация: ищем интервал, где скорость меняет знак
lo_ms = start_ms
hi_ms = end_ms
v_lo = velocity(lo_ms, body, step_ms / 2)
while hi_ms - lo_ms > refine_ms:
mid_ms = (lo_ms + hi_ms) / 2
v_mid = velocity(mid_ms, body, step_ms / 2)
if (v_lo < 0) != (v_mid < 0):
hi_ms = mid_ms
else:
lo_ms = mid_ms
v_lo = v_mid
return (lo_ms + hi_ms) / 2Этот код находит станцию с точностью до 5 секунд, что достаточно для практических целей.
После исправления можно проанализировать, сколько планет обычно ретроградны в момент рождения. Сканирование 73 414 дней с 1900 по 2100 год даёт:
Среднее значение — 2.3. Удивительно, но дат с нулём ретроградных планет меньше, чем с четырьмя. Это контринтуитивно, но объяснимо: ретроградность — обычное явление.
Доля времени в ретроградности равна длине ретроградной дуги, делённой на синодический период. Для внешних планет синодический период стремится к году, и доля приближается к 50% — как у неподвижной звезды из-за аберрации. Венера и Меркурий — внутренние, их ретроградность связана с нижним соединением, но пропорция сохраняется.
Проверьте свой код на наличие вычитания углов. Замените a - b на angular_delta(a, b). Если вы работаете с астрономическими данными, используйте библиотеку astronomy-engine (MIT) — она корректно вычисляет видимые геоцентрические долготы. Это убережёт вас от ложных ретроградных периодов и других ошибок, связанных с циклическими величинами.
Хочешь закрепить знания на практике?
Решай задачи на Algolit — интерактивная платформа для обучения
Начать бесплатно →