worldmap-viewer

git clone https://git.godosa.eu/worldmap-viewer

master

raw · 1776 bytes

// 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] : '';
}