"""Punkty wirtualne liczone analitycznie (LOG-02): mean Node i mean Lilith. Wzory Meeusa (Astronomical Algorithms) w stuleciach juliańskich od J2000 (TT): - Ω — średni węzeł wstępujący orbity Księżyca (mean ascending node). Porusza się zawsze wstecz (~−0,053°/dobę) — stąd węzły są wiecznie Rx. - średnie perygeum orbity Księżyca; mean Lilith (Black Moon) = średnie APOGEUM = perygeum + 180° (~+0,111°/dobę). Wersje TRUE (oskulacyjne) — osobny, późniejszy krok (notatki: mean to historyczny standard i domyślne ustawienie programów). """ from __future__ import annotations from app.engine.formats import norm360 _DAYS_PER_CENTURY = 36525.0 def _t(tt_jd: float) -> float: return (tt_jd - 2451545.0) / _DAYS_PER_CENTURY def mean_lunar_node(tt_jd: float) -> float: """Długość ekliptyczna średniego Węzła Północnego (Ω) [°].""" t = _t(tt_jd) omega = (125.0445479 - 1934.1362891 * t + 0.0020754 * t * t + t ** 3 / 467441.0 - t ** 4 / 60616000.0) return norm360(omega) def mean_lilith(tt_jd: float) -> float: """Długość ekliptyczna mean Lilith (średnie apogeum Księżyca) [°].""" t = _t(tt_jd) perigee = (83.3532465 + 4069.0137287 * t - 0.0103200 * t * t - t ** 3 / 80053.0 + t ** 4 / 18999000.0) return norm360(perigee + 180.0) def point_speed(fn, tt_jd: float, dt_days: float = 0.1) -> float: """Prędkość [°/dobę] punktu analitycznego — różnica po małym kroku.""" a = fn(tt_jd) b = fn(tt_jd + dt_days) return (((b - a + 180.0) % 360.0) - 180.0) / dt_days