PageSourceSearch

https://slateworks.ai/js/planets.js?v=979ea9dc

js slateworks.ai collected 2026-10-05 15:05:03 UTC 5,007 bytes, 164 lines download raw bytes

1/**
2 * planets.js — Planet position computation for slateworks.ai
3 *
4 * Uses Astronomy Engine to compute positions of the 5 naked-eye planets,
5 * Jupiter's Galilean moons, and Saturn's ring tilt. Exposes positions as
6 * celestial XYZ (same coordinate system as star_catalog.js) via
7 * window._planetData for the WebGL renderer in stars_gl.js.
8 *
9 * Requires: astronomy.browser.min.js (Astronomy Engine by Don Cross, MIT)
10 */
11(function () {
12  'use strict';
13
14  if (typeof Astronomy === 'undefined') {
15    console.warn('[planets] Astronomy Engine not loaded');
16    return;
17  }
18
19  var DEG = Math.PI / 180;
20  var RAD = 180 / Math.PI;
21
22  // Planet visual properties: body name + fixed color [r,g,b] in 0-1
23  var PLANET_DEFS = [
24    { body: 'Mercury', color: [1.0, 0.92, 0.85] },
25    { body: 'Venus',   color: [1.0, 1.0,  0.95] },
26    { body: 'Mars',    color: [1.0, 0.6,  0.4 ] },
27    { body: 'Jupiter', color: [1.0, 0.95, 0.85] },
28    { body: 'Saturn',  color: [1.0, 0.90, 0.70] }
29  ];
30
31  var MOON_COLOR = [1.0, 0.95, 0.9];
32  var MOON_NAMES = ['io', 'europa', 'ganymede', 'callisto'];
33
34  // Throttle: recompute every 200ms (5 fps ephemeris, plenty smooth even at 960x)
35  var COMPUTE_INTERVAL = 200;
36  var lastComputeTime = 0;
37  var cached = null;
38
39  // RA/Dec → celestial unit-sphere XYZ (same convention as star_catalog/stars_gl)
40  function raDecToXYZ(raHours, decDeg) {
41    var raRad = raHours * (Math.PI / 12);
42    var decRad = decDeg * DEG;
43    var cd = Math.cos(decRad);
44    return [cd * Math.cos(raRad), Math.sin(decRad), cd * Math.sin(raRad)];
45  }
46
47  // Convert geocentric equatorial XYZ (AU) to RA (hours) and Dec (degrees)
48  function xyzToRADec(x, y, z) {
49    var dist = Math.sqrt(x * x + y * y + z * z);
50    var dec = Math.asin(z / dist) * RAD;
51    var ra = Math.atan2(y, x) * RAD / 15; // deg → hours
52    if (ra < 0) ra += 24;
53    return { ra: ra, dec: dec, dist: dist };
54  }
55
56  function computePlanets(date) {
57    var loc = window._slateworksLocation || { lat: 34.0, lon: -118.25 };
58    var observer = new Astronomy.Observer(loc.lat, loc.lon, 0);
59
60    var planets = [];
61    var jupiterMoons = [];
62    var saturnRingTilt = 0;
63    var jupiterGeo = null;
64    var jupiterMag = -2.5; // fallback
65
66    for (var i = 0; i < PLANET_DEFS.length; i++) {
67      var p = PLANET_DEFS[i];
68
69      // Topocentric equatorial coordinates (RA/Dec), aberration-corrected
70      var eq = Astronomy.Equator(p.body, date, observer, true, true);
71
72      // Apparent magnitude + Saturn ring tilt
73      var illum = Astronomy.Illumination(p.body, date);
74
75      // Celestial unit-sphere XYZ
76      var xyz = raDecToXYZ(eq.ra, eq.dec);
77
78      planets.push({
79        name: p.body,
80        xyz: xyz,
81        ra: eq.ra,
82        dec: eq.dec,
83        mag: illum.mag,
84        color: p.color
85      });
86
87      if (p.body === 'Saturn') {
88        saturnRingTilt = illum.ring_tilt || 0;
89      }
90
91      if (p.body === 'Jupiter') {
92        jupiterGeo = Astronomy.GeoVector('Jupiter', date, true);
93        jupiterMag = illum.mag;
94      }
95    }
96
97    // Galilean moons: offset from Jupiter's geocentric position
98    if (jupiterGeo) {
99      var moons = Astronomy.JupiterMoons(date);
100      for (var m = 0; m < MOON_NAMES.length; m++) {
101        var moonName = MOON_NAMES[m];
102        var moon = moons[moonName];
103
104        // Moon geocentric = Jupiter geocentric + jovicentric offset (all EQJ, AU)
105        var rd = xyzToRADec(
106          jupiterGeo.x + moon.x,
107          jupiterGeo.y + moon.y,
108          jupiterGeo.z + moon.z
109        );
110
111        jupiterMoons.push({
112          name: moonName,
113          xyz: raDecToXYZ(rd.ra, rd.dec),
114          ra: rd.ra,
115          dec: rd.dec,
116          mag: jupiterMag / 2,
117          color: MOON_COLOR
118        });
119      }
120    }
121
122    return {
123      planets: planets,
124      jupiterMoons: jupiterMoons,
125      saturnRingTilt: saturnRingTilt
126    };
127  }
128
129  // Called each frame from the render loop — throttled internally
130  function update() {
131    var now = performance.now();
132    if (cached && now - lastComputeTime < COMPUTE_INTERVAL) {
133      return cached;
134    }
135
136    // Build date from the time system (same logic as stars_gl.js)
137    var date = new Date();
138    var oh = window._secretTimeOverride;
139    if (oh !== undefined && oh !== null) {
140      oh = (typeof oh === 'number') ? oh : parseFloat(oh);
141      // oh is in the active timezone — convert to browser-local for correct UTC
142      var activeTz = (typeof window._slateworksTzOffset === 'number')
143        ? window._slateworksTzOffset : -date.getTimezoneOffset() / 60;
144      var browserTz = -date.getTimezoneOffset() / 60;
145      var browserH = oh - activeTz + browserTz;
146      date = new Date();
147      date.setHours(0, 0, 0, 0);
148      date.setTime(date.getTime() + browserH * 3600000);
149    }
150
151    cached = computePlanets(date);
152    window._planetData = cached;
153    lastComputeTime = now;
154
155    return cached;
156  }
157
158  window._updatePlanets = update;
159
160  // Initial computation
161  update();
162  console.log('[planets] Init OK — 5 planets + 4 Galilean moons');
163
164})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.