mirror of
https://github.com/migatu/astrololo.git
synced 2026-07-14 13:34:38 +00:00
94c3023d3a
Kontynuacja silnika efemeryd o osie i domy. - engine/houses.py: czysta matematyka sferyczna — Asc, MC (z RAMC + ε + φ), cusps dla Whole Sign / Equal / Porphyry, przypisanie obiektu do domu. - SkyfieldEngine.sidereal(): RAMC (lokalny apparent ST) + średnie nachylenie ekliptyki ze Skyfielda. - engine/chart.py: build_chart() składa pełny horoskop (pozycje + osie + domy). - Endpoint /chart/positions rozszerzony o house_system i zwraca angles + cusps + numer domu per obiekt. - Prezentacja: lokalizacja i wybór systemu domów w formularzu, tabela osi, kolumna Dom, rozwijane cusps. Walidacja względem astro.com (30.04.1984, Warszawa): Asc Can 22°10'43", MC Pis 22°35'29" (~1' od referencji); wszystkie przypisania domów Whole Sign zgodne (Sun 11, Mercury 10, Mars 5, ...). 20 testów przechodzi. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
51 lines
1.7 KiB
Python
51 lines
1.7 KiB
Python
"""Złożenie pełnego horoskopu: pozycje + osie + domy (LOG-01 + LOG-05).
|
|
|
|
Silnik-agnostyczne: potrzebuje tylko `positions()` oraz (dla osi/domów)
|
|
`sidereal()`. Jeśli silnik nie umie policzyć czasu gwiazdowego, zwraca same
|
|
pozycje.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from app.engine import houses as H
|
|
from app.engine.base import EphemerisEngine
|
|
from app.engine.formats import SIGNS, in_sign, norm360, sign_index
|
|
from app.engine.models import ChartMoment
|
|
|
|
|
|
def _fmt(name: str, lon: float) -> dict:
|
|
return {
|
|
"name": name,
|
|
"sign": SIGNS[sign_index(lon)],
|
|
"in_sign": in_sign(lon),
|
|
"decimal": round(norm360(lon), 6),
|
|
}
|
|
|
|
|
|
def build_chart(engine: EphemerisEngine, moment: ChartMoment, house_system: str = H.WHOLE_SIGN) -> dict:
|
|
positions = engine.positions(moment)
|
|
result: dict = {"engine": engine.name, "positions": [p.as_dict() for p in positions]}
|
|
|
|
if not hasattr(engine, "sidereal"):
|
|
return result
|
|
|
|
ramc, eps = engine.sidereal(moment)
|
|
asc = H.compute_asc(ramc, eps, moment.lat)
|
|
mc = H.compute_mc(ramc, eps)
|
|
system = house_system if house_system in H.SYSTEMS else H.WHOLE_SIGN
|
|
cusp_list = H.cusps(asc, mc, system)
|
|
|
|
result["house_system"] = system
|
|
result["angles"] = {
|
|
"Asc": _fmt("Asc", asc),
|
|
"MC": _fmt("MC", mc),
|
|
"Dsc": _fmt("Dsc", norm360(asc + 180.0)),
|
|
"IC": _fmt("IC", norm360(mc + 180.0)),
|
|
}
|
|
result["cusps"] = [
|
|
{"house": i + 1, "sign": SIGNS[sign_index(c)], "in_sign": in_sign(c)}
|
|
for i, c in enumerate(cusp_list)
|
|
]
|
|
for pdict, obj in zip(result["positions"], positions):
|
|
pdict["house"] = H.assign_house(obj.longitude, cusp_list)
|
|
return result
|