From fc8b491b6a2045588f4ef81063baa7c53079a1dc Mon Sep 17 00:00:00 2001 From: Eskimue Date: Fri, 3 Apr 2026 16:50:54 +0200 Subject: [PATCH] Goldener henkel berechnung verbessert --- .codex-temp/php-server.err.log | 87 ++++++++++++++++++++++ public/py/__pycache__/api.cpython-314.pyc | Bin 143623 -> 148239 bytes public/py/api.py | 46 +++++++++--- 3 files changed, 124 insertions(+), 9 deletions(-) diff --git a/.codex-temp/php-server.err.log b/.codex-temp/php-server.err.log index e35c176..8b592c0 100644 --- a/.codex-temp/php-server.err.log +++ b/.codex-temp/php-server.err.log @@ -902,3 +902,90 @@ Stack trace: [Fri Apr 3 16:13:22 2026] 127.0.0.1:62960 Accepted [Fri Apr 3 16:13:31 2026] 127.0.0.1:62960 [200]: GET /monatsvorhersage_old.php?year=2026&month=12 [Fri Apr 3 16:13:31 2026] 127.0.0.1:62960 Closing +[Fri Apr 3 16:19:37 2026] 127.0.0.1:55410 Accepted +[Fri Apr 3 16:19:53 2026] 127.0.0.1:55410 [200]: GET /monatsvorhersage_old.php?year=2026&month=3 +[Fri Apr 3 16:19:53 2026] 127.0.0.1:55410 Closing +[Fri Apr 3 16:19:53 2026] 127.0.0.1:52807 Accepted +[Fri Apr 3 16:20:02 2026] 127.0.0.1:52807 [200]: GET /monatsvorhersage_old.php?year=2026&month=10 +[Fri Apr 3 16:20:02 2026] 127.0.0.1:52807 Closing +[Fri Apr 3 16:20:24 2026] 127.0.0.1:51409 Accepted +[Fri Apr 3 16:20:33 2026] 127.0.0.1:51409 [200]: GET /monatsvorhersage_old.php?year=2026&month=10 +[Fri Apr 3 16:20:33 2026] 127.0.0.1:51409 Closing +[Fri Apr 3 16:20:50 2026] 127.0.0.1:60154 Accepted +[Fri Apr 3 16:21:06 2026] 127.0.0.1:60154 [200]: GET /monatsvorhersage_old.php?year=2026&month=3 +[Fri Apr 3 16:21:06 2026] 127.0.0.1:60154 Closing +[Fri Apr 3 16:21:06 2026] 127.0.0.1:51578 Accepted +[Fri Apr 3 16:21:06 2026] 127.0.0.1:64104 Accepted +[Fri Apr 3 16:21:06 2026] 127.0.0.1:51578 [200]: GET /css/style.css +[Fri Apr 3 16:21:06 2026] 127.0.0.1:64104 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 16:21:06 2026] 127.0.0.1:51578 Closing +[Fri Apr 3 16:21:06 2026] 127.0.0.1:64104 Closing +[Fri Apr 3 16:21:06 2026] 127.0.0.1:64109 Accepted +[Fri Apr 3 16:21:06 2026] 127.0.0.1:53635 Accepted +[Fri Apr 3 16:21:06 2026] 127.0.0.1:64109 [200]: GET /images/star16x16.png +[Fri Apr 3 16:21:06 2026] 127.0.0.1:53635 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 16:21:06 2026] 127.0.0.1:64109 Closing +[Fri Apr 3 16:21:06 2026] 127.0.0.1:53635 Closing +[Fri Apr 3 16:21:06 2026] 127.0.0.1:52555 Accepted +[Fri Apr 3 16:21:08 2026] 127.0.0.1:52555 [200]: GET /favicon.ico +[Fri Apr 3 16:21:08 2026] 127.0.0.1:52555 Closing +[Fri Apr 3 16:22:29 2026] 127.0.0.1:53891 Accepted +[Fri Apr 3 16:22:38 2026] 127.0.0.1:53891 [200]: GET /monatsvorhersage_old.php?year=2026&month=9 +[Fri Apr 3 16:22:38 2026] 127.0.0.1:53891 Closing +[Fri Apr 3 16:22:38 2026] 127.0.0.1:52655 Accepted +[Fri Apr 3 16:22:38 2026] 127.0.0.1:52655 [200]: GET /css/style.css +[Fri Apr 3 16:22:38 2026] 127.0.0.1:52655 Closing +[Fri Apr 3 16:22:38 2026] 127.0.0.1:52780 Accepted +[Fri Apr 3 16:22:38 2026] 127.0.0.1:52780 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 16:22:38 2026] 127.0.0.1:52780 Closing +[Fri Apr 3 16:22:38 2026] 127.0.0.1:55211 Accepted +[Fri Apr 3 16:22:38 2026] 127.0.0.1:55211 [200]: GET /images/star16x16.png +[Fri Apr 3 16:22:38 2026] 127.0.0.1:59860 Accepted +[Fri Apr 3 16:22:38 2026] 127.0.0.1:59860 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 16:22:38 2026] 127.0.0.1:55211 Closing +[Fri Apr 3 16:22:38 2026] 127.0.0.1:59860 Closing +[Fri Apr 3 16:22:38 2026] 127.0.0.1:55583 Accepted +[Fri Apr 3 16:22:40 2026] 127.0.0.1:55583 [200]: GET /favicon.ico +[Fri Apr 3 16:22:40 2026] 127.0.0.1:55583 Closing +[Fri Apr 3 16:22:58 2026] 127.0.0.1:52476 Accepted +[Fri Apr 3 16:23:08 2026] 127.0.0.1:52476 [200]: GET /monatsvorhersage_old.php?year=2026&month=10 +[Fri Apr 3 16:23:08 2026] 127.0.0.1:52476 Closing +[Fri Apr 3 16:23:08 2026] 127.0.0.1:60654 Accepted +[Fri Apr 3 16:23:08 2026] 127.0.0.1:64290 Accepted +[Fri Apr 3 16:23:08 2026] 127.0.0.1:60654 [200]: GET /css/style.css +[Fri Apr 3 16:23:08 2026] 127.0.0.1:64290 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 16:23:08 2026] 127.0.0.1:60654 Closing +[Fri Apr 3 16:23:08 2026] 127.0.0.1:64290 Closing +[Fri Apr 3 16:23:08 2026] 127.0.0.1:59075 Accepted +[Fri Apr 3 16:23:08 2026] 127.0.0.1:49458 Accepted +[Fri Apr 3 16:23:08 2026] 127.0.0.1:59075 [200]: GET /images/star16x16.png +[Fri Apr 3 16:23:08 2026] 127.0.0.1:49458 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 16:23:08 2026] 127.0.0.1:59075 Closing +[Fri Apr 3 16:23:08 2026] 127.0.0.1:49458 Closing +[Fri Apr 3 16:23:08 2026] 127.0.0.1:61695 Accepted +[Fri Apr 3 16:23:09 2026] 127.0.0.1:61695 [200]: GET /favicon.ico +[Fri Apr 3 16:23:09 2026] 127.0.0.1:61695 Closing +[Fri Apr 3 16:24:34 2026] 127.0.0.1:57467 Accepted +[Fri Apr 3 16:24:50 2026] 127.0.0.1:57467 [200]: GET /monatsvorhersage_old.php?year=2026&month=3 +[Fri Apr 3 16:24:50 2026] 127.0.0.1:57467 Closing +[Fri Apr 3 16:24:50 2026] 127.0.0.1:58591 Accepted +[Fri Apr 3 16:25:00 2026] 127.0.0.1:58591 [200]: GET /monatsvorhersage_old.php?year=2026&month=10 +[Fri Apr 3 16:25:00 2026] 127.0.0.1:58591 Closing +[Fri Apr 3 16:25:00 2026] 127.0.0.1:54076 Accepted +[Fri Apr 3 16:25:00 2026] 127.0.0.1:61845 Accepted +[Fri Apr 3 16:25:10 2026] 127.0.0.1:54076 [200]: GET /monatsvorhersage_old.php?year=2026&month=10 +[Fri Apr 3 16:25:10 2026] 127.0.0.1:54076 Closing +[Fri Apr 3 16:25:10 2026] 127.0.0.1:60099 Accepted +[Fri Apr 3 16:25:10 2026] 127.0.0.1:61845 [200]: GET /css/style.css +[Fri Apr 3 16:25:10 2026] 127.0.0.1:60099 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 16:25:10 2026] 127.0.0.1:61845 Closing +[Fri Apr 3 16:25:10 2026] 127.0.0.1:60099 Closing +[Fri Apr 3 16:25:10 2026] 127.0.0.1:57577 Accepted +[Fri Apr 3 16:25:10 2026] 127.0.0.1:57577 [200]: GET /images/star16x16.png +[Fri Apr 3 16:25:10 2026] 127.0.0.1:58971 Accepted +[Fri Apr 3 16:25:10 2026] 127.0.0.1:58971 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 16:25:10 2026] 127.0.0.1:57577 Closing +[Fri Apr 3 16:25:10 2026] 127.0.0.1:58971 Closing +[Fri Apr 3 16:25:10 2026] 127.0.0.1:65351 Accepted +[Fri Apr 3 16:25:12 2026] 127.0.0.1:65351 [200]: GET /favicon.ico +[Fri Apr 3 16:25:12 2026] 127.0.0.1:65351 Closing diff --git a/public/py/__pycache__/api.cpython-314.pyc b/public/py/__pycache__/api.cpython-314.pyc index 9a9d1fcb644db9e1a436a46565cd78b476d3c07d..4ef38dcb25ebdad2fffcb057e22fd2694172bdc7 100644 GIT binary patch delta 10121 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 Zf2O)MOOTwI!d&o?)8dU%e!Zs<`9Ivjjf?;Q delta 7898 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 P3c?X+ diff --git a/public/py/api.py b/public/py/api.py index c0584d4..4208e1f 100644 --- a/public/py/api.py +++ b/public/py/api.py @@ -494,19 +494,47 @@ def action_golden_handle_for_month(args: list[str]) -> dict: else: local_end = datetime(year, month + 1, 1, 0, 0, 0, tzinfo=tz) - # Approximate the Golden Handle geometrically by the effective selenographic - # colongitude over Montes Jura/Sinus Iridum (roughly 44 N, 36 W), - # corrected by libration. Empirically, the best-fit target shifts with - # libration in latitude by several tenths of a degree, i.e. by hours. - def target_colongitude(elat_deg: float) -> float: - return 33.385316705346064 + 0.11176238230626076 * elat_deg + 0.0734267792065295 * elat_deg * elat_deg + # Minimal physical model for the Golden Handle: + # solve the time when the floor of Sinus Iridum is still below sunrise + # by half of the topographic advance angle of the Jura rim. + moon_radius_km = 1737.4 + floor_latitude_deg = 42.0 + floor_longitude_west_deg = 35.5 + relief_height_difference_km = 1.18 - def golden_handle_metric(dt_utc: datetime) -> float: + def relief_advance_angle_deg() -> float: + return math.degrees( + math.acos(moon_radius_km / (moon_radius_km + relief_height_difference_km)) + ) + + def solar_selenographic_coordinates(dt_utc: datetime) -> tuple[float, float]: time_value = dt_to_time(dt_utc) phase_deg = normalize_degrees(astronomy.MoonPhase(time_value)) libration = astronomy.Libration(time_value) - effective_colongitude = normalize_degrees(phase_deg - 90.0 - float(libration.elon)) - return normalize_signed_degrees(effective_colongitude - target_colongitude(float(libration.elat))) + axis_latitudes = calculate_moon_axis_latitudes(time_value) + + # Approximate selenographic solar longitude from colongitude using + # west-positive longitude for the lunar surface model. + colongitude_deg = normalize_degrees(phase_deg - 90.0 - float(libration.elon)) + solar_longitude_west_deg = normalize_signed_degrees(colongitude_deg - 90.0) + solar_latitude_deg = float(axis_latitudes["subsolar_latitude"]) + return solar_longitude_west_deg, solar_latitude_deg + + def floor_solar_altitude_deg(dt_utc: datetime) -> float: + solar_longitude_west_deg, solar_latitude_deg = solar_selenographic_coordinates(dt_utc) + phi = math.radians(floor_latitude_deg) + lam_f = math.radians(floor_longitude_west_deg) + lam_s = math.radians(solar_longitude_west_deg) + b_s = math.radians(solar_latitude_deg) + x = ( + math.sin(phi) * math.sin(b_s) + + math.cos(phi) * math.cos(b_s) * math.cos(lam_f - lam_s) + ) + x = max(-1.0, min(1.0, x)) + return math.degrees(math.asin(x)) + + def golden_handle_metric(dt_utc: datetime) -> float: + return floor_solar_altitude_deg(dt_utc) + relief_advance_angle_deg() / 2.0 def refine_peak_time(left_utc: datetime, right_utc: datetime) -> datetime: left = left_utc