Jupiter-Monatsübersicht ausrichten und GRS hervorheben

This commit is contained in:
2026-09-12 09:55:45 +02:00
parent 1725d9db27
commit d4c44c55d2
+53 -4
View File
@@ -206,7 +206,16 @@ const KM_TO_DISPLAY = JUPITER_DISPLAY_RADIUS / JUPITER_RADIUS_KM;
// Jupiter System III (Referenz): 9h 55m 29.7s — System II (GRS): 9h 55m 40.632s // Jupiter System III (Referenz): 9h 55m 29.7s — System II (GRS): 9h 55m 40.632s
const GRS_SYSTEM_II_PERIOD_DAYS = 35740.632 / 86400; const GRS_SYSTEM_II_PERIOD_DAYS = 35740.632 / 86400;
// GRS-Kalibrierung: Referenzzeitpunkt und Rotationswinkel bei Transit // GRS-Kalibrierung: Referenzzeitpunkt und Rotationswinkel bei Transit.
//
// WICHTIG: Die Transitzeiten von Sky & Telescope sind beobachtete/geozentrische
// UT-Zeitpunkte. Die Lichtlaufzeit Jupiter→Erde ist für den jeweiligen
// Referenzzeitpunkt daher bereits enthalten. Hier NICHT nochmals pauschal die
// Jupiter-Lichtlaufzeit abziehen, sonst würden wir doppelt korrigieren.
// Bei der Monatsprognose wird aktuell die GRS-Rotation ab diesem beobachteten
// Referenzzeitpunkt mit der System-II-Periode fortgeschrieben. Eine mögliche
// spätere Verbesserung wäre, zusätzlich die Änderung der Lichtlaufzeit zwischen
// Referenzzeitpunkt und Prognosezeitpunkt zu berücksichtigen.
let grsRefDate = new Date(0); let grsRefDate = new Date(0);
let grsRefAngle = 0; let grsRefAngle = 0;
@@ -1442,13 +1451,43 @@ function generateEphemerisCanvas() {
return result; return result;
} }
// Scheinbare Ost-West-Projektion für die Monatsgrafik.
// Die Jupiter-Mondvektoren liegen in EQJ. Für die Ansicht von der Erde
// projizieren wir sie auf die lokale Himmels-Ost-West-Achse. Für diese
// Darstellung steht Westen links und Osten rechts.
function getApparentWestBasis(date) {
const emissionDate = getJupiterEmissionDate(date);
const geo = AstronomyEngine.GeoVector(
AstronomyEngine.Body.Jupiter,
emissionDate,
true
);
const equatorialLength = Math.hypot(geo.x, geo.y);
if (equatorialLength === 0) {
return { x: 1, y: 0, z: 0 };
}
// Richtung zunehmender Rektaszension = Himmels-Osten.
const east = {
x: -geo.y / equatorialLength,
y: geo.x / equatorialLength,
z: 0
};
// Westen wird links gezeichnet, daher ist rechts die positive Ostseite.
return east;
}
function getApparentWestOffset(state, westBasis) {
return state.x * westBasis.x + state.y * westBasis.y + state.z * westBasis.z;
}
const points = []; const points = [];
for (let d = 1; d <= daysInMonth; d++) { for (let d = 1; d <= daysInMonth; d++) {
for (let s = 0; s < STEPS_PER_DAY; s++) { for (let s = 0; s < STEPS_PER_DAY; s++) {
const date = new Date(Date.UTC(year, month, d, s * STEP_HOURS, 0, 0)); const date = new Date(Date.UTC(year, month, d, s * STEP_HOURS, 0, 0));
const states = getJupiterMoonStates(date); const states = getJupiterMoonStates(date);
const westBasis = getApparentWestBasis(date);
const moonX = {}; const moonX = {};
MOON_KEYS.forEach(key => { moonX[key] = states[key].x; }); MOON_KEYS.forEach(key => { moonX[key] = getApparentWestOffset(states[key], westBasis); });
const nearDisk = getMoonsNearDisk(date, states); const nearDisk = getMoonsNearDisk(date, states);
points.push({ d, t: (d - 1) + s / STEPS_PER_DAY, date, moonX, nearDisk }); points.push({ d, t: (d - 1) + s / STEPS_PER_DAY, date, moonX, nearDisk });
} }
@@ -1484,6 +1523,8 @@ function generateEphemerisCanvas() {
}); });
// GRS-Transitzeiten: alle Transits im Monat berechnen // GRS-Transitzeiten: alle Transits im Monat berechnen
function getGrsTransitsForDay(d) { function getGrsTransitsForDay(d) {
// grsRefDate ist bereits eine scheinbare, von der Erde aus beobachtete
// Transitzeit. Deshalb keine erneute pauschale Lichtlaufzeit-Korrektur.
if (!grsRefDate || grsRefDate.getTime() === 0) return []; if (!grsRefDate || grsRefDate.getTime() === 0) return [];
const dayStart = new Date(Date.UTC(year, month, d, 0, 0, 0)).getTime(); const dayStart = new Date(Date.UTC(year, month, d, 0, 0, 0)).getTime();
const dayEnd = dayStart + 86400000; const dayEnd = dayStart + 86400000;
@@ -1505,8 +1546,9 @@ function generateEphemerisCanvas() {
for (let d = 1; d <= daysInMonth; d++) { for (let d = 1; d <= daysInMonth; d++) {
const date = new Date(Date.UTC(year, month, d, 12, 0, 0)); const date = new Date(Date.UTC(year, month, d, 12, 0, 0));
const states = getJupiterMoonStates(date); const states = getJupiterMoonStates(date);
const westBasis = getApparentWestBasis(date);
const moonX = {}; const moonX = {};
MOON_KEYS.forEach(key => { moonX[key] = states[key].x; }); MOON_KEYS.forEach(key => { moonX[key] = getApparentWestOffset(states[key], westBasis); });
const grsTransits = getGrsTransitsForDay(d); const grsTransits = getGrsTransitsForDay(d);
rows.push({ d, moonX, grsTransits }); rows.push({ d, moonX, grsTransits });
} }
@@ -1545,7 +1587,7 @@ function generateEphemerisCanvas() {
moonRim: 'rgba(0,0,0,0.2)', moonRim: 'rgba(0,0,0,0.2)',
legBg: 'rgba(240,240,245,0.9)', legBorder: 'rgba(100,80,20,0.3)', legBg: 'rgba(240,240,245,0.9)', legBorder: 'rgba(100,80,20,0.3)',
legText: 'rgba(40,40,80,0.8)', legText: 'rgba(40,40,80,0.8)',
grsCol: '#c05000', grsCol: '#d02020',
footText: 'rgba(60,60,100,0.5)', footText: 'rgba(60,60,100,0.5)',
titleLine: 'rgba(120,90,20,0.4)', titleLine: 'rgba(120,90,20,0.4)',
}; };
@@ -1572,6 +1614,13 @@ function generateEphemerisCanvas() {
c.textAlign = 'center'; c.textAlign = 'center';
c.fillText(`Jupitermonde — ${monthName}`, W / 2, 56); c.fillText(`Jupitermonde — ${monthName}`, W / 2, 56);
c.fillStyle = COL.footText;
c.font = '18px monospace';
c.textAlign = 'left';
c.fillText('West', MARGIN_LEFT, MARGIN_TOP - 12);
c.textAlign = 'right';
c.fillText('Ost', MARGIN_LEFT + chartW, MARGIN_TOP - 12);
// Goldene Trennlinie unter Titel // Goldene Trennlinie unter Titel
const tl = c.createLinearGradient(MARGIN_LEFT, 0, MARGIN_LEFT + chartW, 0); const tl = c.createLinearGradient(MARGIN_LEFT, 0, MARGIN_LEFT + chartW, 0);
tl.addColorStop(0, 'transparent'); tl.addColorStop(0, 'transparent');