solargod/js/bodies.js
monsterrobotparty be5f8ad544 🌖 selene: real NASA/USGS maps + tidal lock for the major moons (opus)
- source 8 public-domain equirectangular mosaics (io/europa/ganymede/callisto/
  titan/triton/charon/phobos) from usgs astrogeology, downscale to 1024x512 jpg
  (0.92 mb added total, each <=143 kb); credits.md lists source/mission/license
- bodies.js: texture field on the 8 sourced moon entries only
- moons.js: load textures via ctx.loadTextureInto (same path as planets.js, so
  the moon's own 2k map also renders now); flat-color 404 fallback preserved
- moons.js tick: tidal lock rotation.y = 2pi*(jd-J2000)/period + pi (signed
  period gives retrograde spin for free)
2026-07-16 09:55:07 +10:00

128 lines
7.0 KiB
JavaScript

// SOLARGOD physical-data registry — radii, axial tilts, rotation, colors, texture
// paths, moon orbits. Radii are the brief §8 values (JPL). Tilts/rotation are
// canonical IAU/JPL phys_par values; every textured body has a flat-color
// procedural fallback so a missing texture degrades gracefully (brief §7).
//
// Fields: name, type, radiusKm, axialTiltDeg, rotationHours (neg = retrograde),
// color (fallback), texture (under CONFIG.textures.path, or null), parent,
// ephemId (planet → ephem.js key) | moonOrbit {aKm, periodDays (neg = retro)} |
// elements (small-body epoch elements). rings when present.
export const BODIES = {
sun: {
name: 'Sun', type: 'star', radiusKm: 695700, axialTiltDeg: 7.25,
rotationHours: 609.12, color: '#ffdd88', texture: '2k_sun.jpg', parent: null,
},
mercury: {
name: 'Mercury', type: 'planet', radiusKm: 2439.7, axialTiltDeg: 0.034,
rotationHours: 1407.6, color: '#9c8b7a', texture: '2k_mercury.jpg',
parent: 'sun', ephemId: 'mercury',
},
venus: {
name: 'Venus', type: 'planet', radiusKm: 6051.8, axialTiltDeg: 177.36,
rotationHours: -5832.5, color: '#d9b382', texture: '2k_venus_surface.jpg',
parent: 'sun', ephemId: 'venus',
},
earth: {
name: 'Earth', type: 'planet', radiusKm: 6371.0, axialTiltDeg: 23.44,
rotationHours: 23.9345, color: '#4b7bd4', texture: '2k_earth_daymap.jpg',
parent: 'sun', ephemId: 'earth',
},
mars: {
name: 'Mars', type: 'planet', radiusKm: 3389.5, axialTiltDeg: 25.19,
rotationHours: 24.6229, color: '#c1440e', texture: '2k_mars.jpg',
parent: 'sun', ephemId: 'mars',
},
jupiter: {
name: 'Jupiter', type: 'planet', radiusKm: 69911, axialTiltDeg: 3.13,
rotationHours: 9.925, color: '#d8ca9d', texture: '2k_jupiter.jpg',
parent: 'sun', ephemId: 'jupiter',
},
saturn: {
name: 'Saturn', type: 'planet', radiusKm: 58232, axialTiltDeg: 26.73,
rotationHours: 10.656, color: '#e3d9b0', texture: '2k_saturn.jpg',
parent: 'sun', ephemId: 'saturn',
rings: { innerKm: 74500, outerKm: 140220, texture: '2k_saturn_ring_alpha.png' },
},
uranus: {
name: 'Uranus', type: 'planet', radiusKm: 25362, axialTiltDeg: 97.77,
rotationHours: -17.24, color: '#b2e5e8', texture: '2k_uranus.jpg',
parent: 'sun', ephemId: 'uranus',
rings: { innerKm: 41000, outerKm: 51000, texture: null, color: '#8fa3a8' },
},
neptune: {
name: 'Neptune', type: 'planet', radiusKm: 24622, axialTiltDeg: 28.32,
rotationHours: 16.11, color: '#3f66d9', texture: '2k_neptune.jpg',
parent: 'sun', ephemId: 'neptune',
},
// ---- moons (circular orbits in parent's equatorial plane; a[km], period[d]) ----
moon: { name: 'Moon', type: 'moon', radiusKm: 1737.4, axialTiltDeg: 6.68,
rotationHours: 655.728, color: '#bcbcbc', texture: '2k_moon.jpg',
parent: 'earth', moonOrbit: { aKm: 384400, periodDays: 27.322 } },
phobos: { name: 'Phobos', type: 'moon', radiusKm: 11.27, color: '#8a7c6e',
texture: '1k_phobos.jpg', parent: 'mars', moonOrbit: { aKm: 9378, periodDays: 0.319 } },
deimos: { name: 'Deimos', type: 'moon', radiusKm: 6.2, color: '#9a8c7a',
texture: null, parent: 'mars', moonOrbit: { aKm: 23459, periodDays: 1.262 } },
io: { name: 'Io', type: 'moon', radiusKm: 1821.6, color: '#e8d24b',
texture: '1k_io.jpg', parent: 'jupiter', moonOrbit: { aKm: 421700, periodDays: 1.769 } },
europa: { name: 'Europa', type: 'moon', radiusKm: 1560.8, color: '#c9b79c',
texture: '1k_europa.jpg', parent: 'jupiter', moonOrbit: { aKm: 671034, periodDays: 3.551 } },
ganymede: { name: 'Ganymede', type: 'moon', radiusKm: 2634.1, color: '#9b8e7e',
texture: '1k_ganymede.jpg', parent: 'jupiter', moonOrbit: { aKm: 1070412, periodDays: 7.155 } },
callisto: { name: 'Callisto', type: 'moon', radiusKm: 2410.3, color: '#6b5f52',
texture: '1k_callisto.jpg', parent: 'jupiter', moonOrbit: { aKm: 1882709, periodDays: 16.689 } },
mimas: { name: 'Mimas', type: 'moon', radiusKm: 198.2, color: '#c8c8c8',
texture: null, parent: 'saturn', moonOrbit: { aKm: 185539, periodDays: 0.942 } },
enceladus: { name: 'Enceladus', type: 'moon', radiusKm: 252.1, color: '#f0f0f0',
texture: null, parent: 'saturn', moonOrbit: { aKm: 238042, periodDays: 1.370 } },
tethys: { name: 'Tethys', type: 'moon', radiusKm: 531.1, color: '#d6d6d6',
texture: null, parent: 'saturn', moonOrbit: { aKm: 294672, periodDays: 1.888 } },
dione: { name: 'Dione', type: 'moon', radiusKm: 561.4, color: '#cfcfcf',
texture: null, parent: 'saturn', moonOrbit: { aKm: 377415, periodDays: 2.737 } },
rhea: { name: 'Rhea', type: 'moon', radiusKm: 763.8, color: '#c4c4c4',
texture: null, parent: 'saturn', moonOrbit: { aKm: 527068, periodDays: 4.518 } },
titan: { name: 'Titan', type: 'moon', radiusKm: 2574.7, color: '#d9a441',
texture: '1k_titan.jpg', parent: 'saturn', moonOrbit: { aKm: 1221870, periodDays: 15.945 } },
iapetus: { name: 'Iapetus', type: 'moon', radiusKm: 734.5, color: '#8a7a5e',
texture: null, parent: 'saturn', moonOrbit: { aKm: 3560851, periodDays: 79.33 } },
miranda: { name: 'Miranda', type: 'moon', radiusKm: 235.8, color: '#b8bcc0',
texture: null, parent: 'uranus', moonOrbit: { aKm: 129900, periodDays: 1.413 } },
ariel: { name: 'Ariel', type: 'moon', radiusKm: 578.9, color: '#c6cacd',
texture: null, parent: 'uranus', moonOrbit: { aKm: 190900, periodDays: 2.520 } },
umbriel: { name: 'Umbriel', type: 'moon', radiusKm: 584.7, color: '#7f8488',
texture: null, parent: 'uranus', moonOrbit: { aKm: 266000, periodDays: 4.144 } },
titania: { name: 'Titania', type: 'moon', radiusKm: 788.4, color: '#b0b4b8',
texture: null, parent: 'uranus', moonOrbit: { aKm: 436300, periodDays: 8.706 } },
oberon: { name: 'Oberon', type: 'moon', radiusKm: 761.4, color: '#9aa0a4',
texture: null, parent: 'uranus', moonOrbit: { aKm: 583500, periodDays: 13.46 } },
// Triton is retrograde — encoded via the negative-period convention (brief §8).
triton: { name: 'Triton', type: 'moon', radiusKm: 1353.4, color: '#d6cfc4',
texture: '1k_triton.jpg', parent: 'neptune', moonOrbit: { aKm: 354759, periodDays: -5.877 } },
// ---- Pluto system (small-body epoch elements; texture-less spheres) ----
pluto: {
name: 'Pluto', type: 'dwarf', radiusKm: 1188.3, axialTiltDeg: 122.53,
rotationHours: -153.2928, color: '#d9c8a9', texture: null, parent: 'sun',
// JPL SBDB J2000 osculating elements (epoch 2451545.0 TDB).
elements: { a: 39.48168677, e: 0.24880766, i: 17.14175, om: 110.30347,
w: 113.76329, ma: 14.86012204, epoch: 2451545.0 },
},
charon: { name: 'Charon', type: 'moon', radiusKm: 606.0, color: '#b3a894',
texture: '1k_charon.jpg', parent: 'pluto', moonOrbit: { aKm: 19591, periodDays: 6.387 } },
};
// Ordered planet ids (draw / menu order).
export const PLANET_ORDER = ['mercury', 'venus', 'earth', 'mars', 'jupiter', 'saturn', 'uranus', 'neptune'];
// Moons grouped by parent.
export function moonsOf(parentId) {
return Object.entries(BODIES)
.filter(([, b]) => b.type === 'moon' && b.parent === parentId)
.map(([id]) => id);
}