// sky.js — sun geometry (pure), values from planet.js. Viewer convention: day 0 = northern spring equinox, // moment 0 = midnight at longitude 0°. Circular orbit. A day has in-world moments (units.moment_s) or minutes; // a sun-locked world keeps its sun still. import { toVec } from './geo.js'; import { PLANET } from './planet.js'; export const TILT_DEG = PLANET.tilt_deg; export const YEAR_DAYS = Math.max(1, Math.round(PLANET.year_days)); export const MOMENT_S = PLANET.moment_s || 60; export const DAY_MOMENTS = Math.round(PLANET.day_hours * 3600 / MOMENT_S); const q = YEAR_DAYS / 4; export const SEASONS = TILT_DEG > 0 ? [[0, 'northern spring equinox'], [q, 'northern midsummer'], [2 * q, 'northern autumn equinox'], [3 * q, 'northern midwinter'], [YEAR_DAYS, 'northern spring equinox']] : []; const D = Math.PI / 180; export function subsolar(day, moment) { if (PLANET.sun_lock) return { lat: PLANET.sun_lock[0], lon: PLANET.sun_lock[1] }; const t = day + moment / DAY_MOMENTS; const lat = Math.asin(Math.sin(TILT_DEG * D) * Math.sin((2 * Math.PI * t) / YEAR_DAYS)) / D; const lon = ((((180 - (360 * moment) / DAY_MOMENTS + 180) % 360) + 360) % 360) - 180; return { lat, lon }; } export function sunVec(day, moment) { const s = subsolar(day, moment); return toVec(s.lat, s.lon); } export function dayFraction(lat, day) { const dec = subsolar(day, 0).lat * D; // declination at the start of the day const phi = Math.max(-89.9999, Math.min(89.9999, lat)) * D; const x = -Math.tan(phi) * Math.tan(dec); if (x <= -1) return 1; if (x >= 1) return 0; return Math.acos(x) / Math.PI; } export function seasonName(day) { const hit = SEASONS.find(([d]) => Math.abs(day - d) <= Math.min(2, YEAR_DAYS / 20)); return hit ? hit[1] : ''; }