Correct lunar tilt and real angular sizes

This commit is contained in:
vini 2026-07-19 15:23:55 -03:00
parent 44fb0b09a6
commit e262395fb3

View file

@ -1269,14 +1269,16 @@ const TWINKLE_MAG = 4.0; // até esta magnitude a estrela cintila; acima é e
const DEG = Math.PI / 180; const DEG = Math.PI / 180;
window.__skyTimeOffset = 0; // debug: ms somados ao relógio p/ testar a rotação window.__skyTimeOffset = 0; // debug: ms somados ao relógio p/ testar a rotação
const PLANET_SPECS = [ const PLANET_SPECS = [
[Astronomy.Body.Mercury, 'Mercúrio', [205, 190, 165]], [Astronomy.Body.Mercury, 'Mercúrio', [205, 190, 165], 2439.7],
[Astronomy.Body.Venus, 'Vênus', [255, 232, 180]], [Astronomy.Body.Venus, 'Vênus', [255, 232, 180], 6051.8],
[Astronomy.Body.Mars, 'Marte', [255, 120, 82]], [Astronomy.Body.Mars, 'Marte', [255, 120, 82], 3389.5],
[Astronomy.Body.Jupiter, 'Júpiter', [255, 218, 170]], [Astronomy.Body.Jupiter, 'Júpiter', [255, 218, 170], 69911],
[Astronomy.Body.Saturn, 'Saturno', [238, 205, 135]], [Astronomy.Body.Saturn, 'Saturno', [238, 205, 135], 58232],
[Astronomy.Body.Uranus, 'Urano', [145, 225, 235]], [Astronomy.Body.Uranus, 'Urano', [145, 225, 235], 25362],
[Astronomy.Body.Neptune, 'Netuno', [105, 150, 255]], [Astronomy.Body.Neptune, 'Netuno', [105, 150, 255], 24622],
]; ];
const KM_PER_AU = 149597870.7;
const MOON_RADIUS_KM = 1737.4;
let solarSystemFrame = { moon: null, planets: [] }; let solarSystemFrame = { moon: null, planets: [] };
let skyTimeScale = 1; let skyTimeScale = 1;
let skyClockRealMs = Date.now(); let skyClockRealMs = Date.now();
@ -1823,36 +1825,35 @@ function updateSolarSystem(date, lst, W, H, horizonPx) {
if (typeof Astronomy === 'undefined') return; if (typeof Astronomy === 'undefined') return;
try { try {
const observer = new Astronomy.Observer(obsLat, obsLon, 0); const observer = new Astronomy.Observer(obsLat, obsLon, 0);
const bodyCoordinates = body => { const bodyCoordinates = (body, aberration = true) => {
const eq = Astronomy.Equator(body, date, observer, true, true); const eq = Astronomy.Equator(body, date, observer, true, aberration);
const aa = altAz(eq.ra * 15, eq.dec, lst); const aa = altAz(eq.ra * 15, eq.dec, lst);
const sc = skyToScreen(aa.alt, aa.az, W, horizonPx); const sc = skyToScreen(aa.alt, aa.az, W, horizonPx);
return { eq, aa, sc }; return { eq, aa, sc };
}; };
const projectBody = body => { const moonCoords = bodyCoordinates(Astronomy.Body.Moon, false);
const coords = bodyCoordinates(body); const sunCoords = bodyCoordinates(Astronomy.Body.Sun, false);
return coords.sc ? { ...coords.sc, alt: coords.aa.alt, az: coords.aa.az } : null;
};
const moonCoords = bodyCoordinates(Astronomy.Body.Moon);
const sunCoords = bodyCoordinates(Astronomy.Body.Sun);
const moonScreen = moonCoords.sc const moonScreen = moonCoords.sc
? { ...moonCoords.sc, alt: moonCoords.aa.alt, az: moonCoords.aa.az } ? { ...moonCoords.sc, alt: moonCoords.aa.alt, az: moonCoords.aa.az }
: null; : null;
const phase = Astronomy.MoonPhase(date); const phase = Astronomy.MoonPhase(date);
const moonIllumination = Astronomy.Illumination(Astronomy.Body.Moon, date); const moonIllumination = Astronomy.Illumination(Astronomy.Body.Moon, date);
const moonRadius = Math.max(12, Math.min(22, H * 0.0085)); const angularRadiusPx = (radiusKm, distanceAu) =>
const deltaAz = (((sunCoords.aa.az - moonCoords.aa.az) % 360 + 540) % 360 - 180) * DEG; Math.asin(Math.min(1, radiusKm / (distanceAu * KM_PER_AU))) / DEG *
const moonAlt = moonCoords.aa.alt * DEG, sunAlt = sunCoords.aa.alt * DEG; (horizonPx / ALT_TOP);
const bearing = Math.atan2( const moonRadius = angularRadiusPx(MOON_RADIUS_KM, moonCoords.eq.dist);
Math.sin(deltaAz) * Math.cos(sunAlt),
Math.cos(moonAlt) * Math.sin(sunAlt) - /* Transformação vetorial oficial do exemplo camera.js do Astronomy
Math.sin(moonAlt) * Math.cos(sunAlt) * Math.cos(deltaAz) Engine: ângulo do limbo claro em relação ao alto do horizonte. */
const moonHorizontal = Astronomy.Horizon(
date, observer, moonCoords.eq.ra, moonCoords.eq.dec, false
); );
const brightDx = Math.sin(bearing) / let cameraRotation = Astronomy.Rotation_EQD_HOR(date, observer);
Math.max(0.16, Math.abs(Math.cos(moonAlt))) * (W / FOV_AZ); cameraRotation = Astronomy.Pivot(cameraRotation, 2, moonHorizontal.azimuth);
const brightDy = -Math.cos(bearing) * (horizonPx / ALT_TOP); cameraRotation = Astronomy.Pivot(cameraRotation, 1, moonHorizontal.altitude);
const brightAngle = Math.atan2(brightDy, brightDx); const sunCameraVector = Astronomy.RotateVector(cameraRotation, sunCoords.eq.vec);
const brightTilt = Math.atan2(sunCameraVector.y, sunCameraVector.z);
const brightAngle = -Math.PI / 2 - brightTilt;
const moon = moonScreen ? { const moon = moonScreen ? {
...moonScreen, ...moonScreen,
radius: moonRadius, radius: moonRadius,
@ -1863,14 +1864,14 @@ function updateSolarSystem(date, lst, W, H, horizonPx) {
} : null; } : null;
const planets = []; const planets = [];
for (const [body, name, color] of PLANET_SPECS) { for (const [body, name, color, radiusKm] of PLANET_SPECS) {
const screen = projectBody(body); const coords = bodyCoordinates(body);
if (!screen) continue; if (!coords.sc) continue;
const illumination = Astronomy.Illumination(body, date); const illumination = Astronomy.Illumination(body, date);
planets.push({ planets.push({
...screen, name, color, body, ...coords.sc, alt: coords.aa.alt, az: coords.aa.az, name, color, body,
magnitude: illumination.mag, magnitude: illumination.mag,
radius: Math.max(1.8, Math.min(5.2, 3.45 - illumination.mag * 0.46)), radius: Math.max(0.55, angularRadiusPx(radiusKm, coords.eq.dist)),
}); });
} }
solarSystemFrame = { moon, planets }; solarSystemFrame = { moon, planets };
@ -1886,7 +1887,7 @@ function drawSolarSystem(c) {
const fade = extinction(moon.alt); const fade = extinction(moon.alt);
c.globalAlpha = fade; c.globalAlpha = fade;
c.shadowColor = 'rgba(205,220,255,0.7)'; c.shadowColor = 'rgba(205,220,255,0.7)';
c.shadowBlur = moon.radius * 1.25; c.shadowBlur = Math.max(2, moon.radius * 1.25);
c.translate(moon.x, moon.y); c.translate(moon.x, moon.y);
c.rotate(moon.brightAngle); c.rotate(moon.brightAngle);
c.drawImage(moon.texture, -moon.radius, -moon.radius, c.drawImage(moon.texture, -moon.radius, -moon.radius,
@ -1904,23 +1905,17 @@ function drawSolarSystem(c) {
c.save(); c.save();
c.globalAlpha = fade; c.globalAlpha = fade;
c.shadowColor = `rgba(${r},${g},${b},0.95)`; c.shadowColor = `rgba(${r},${g},${b},0.95)`;
c.shadowBlur = planet.radius * 3.2; c.shadowBlur = Math.max(2.5, 5.5 - planet.magnitude * 0.45);
c.fillStyle = `rgb(${r},${g},${b})`; c.fillStyle = `rgb(${r},${g},${b})`;
c.beginPath(); c.beginPath();
c.arc(planet.x, planet.y, planet.radius, 0, Math.PI * 2); c.arc(planet.x, planet.y, planet.radius, 0, Math.PI * 2);
c.fill(); c.fill();
if (planet.body === Astronomy.Body.Saturn) { if (showConstellations) {
c.strokeStyle = `rgba(${r},${g},${b},0.82)`; c.shadowColor = 'rgba(4,8,20,0.95)';
c.lineWidth = Math.max(1, planet.radius * 0.34); c.shadowBlur = 4;
c.beginPath(); c.fillStyle = `rgba(${r},${g},${b},0.92)`;
c.ellipse(planet.x, planet.y, planet.radius * 1.8, c.fillText(planet.name, planet.x + planet.radius + 7, planet.y - 1);
planet.radius * 0.62, -0.18, 0, Math.PI * 2);
c.stroke();
} }
c.shadowColor = 'rgba(4,8,20,0.95)';
c.shadowBlur = 4;
c.fillStyle = `rgba(${r},${g},${b},0.92)`;
c.fillText(planet.name, planet.x + planet.radius + 7, planet.y - 1);
c.restore(); c.restore();
} }
c.restore(); c.restore();