Files
martinfencl.eu/locenice2/js/solar.js
T
martin.fencl ba7790daba
continuous-integration/drone/push Build is passing
feat: Add legacy shaders, model I/O, and project panel functionality
- Introduced `legacy-shaders.js` containing vertex and fragment shaders for rendering.
- Implemented `model-io.js` for parsing and encoding GLB files, ensuring compatibility with glTF 2.0.
- Created `project-panel.js` to manage project resources and survey overlays, enhancing user interaction.
- Added `solar.js` for calculating solar positions based on UTC time, latitude, and longitude.
- Developed `three-renderer.js` as a standard backend for Three.js, managing scene rendering and material synchronization.
- Included a new GLB model `dum.glb` for testing and demonstration purposes.
- Established `data_checks.mjs` for validating model data and ensuring integrity of assets.
- Created `prepare_export.py` to facilitate Blender GLB exports, maintaining material and node references.
- Added `vendor_three.py` to download and configure a local version of Three.js for the project.
2026-10-22 01:04:21 +02:00

24 lines
1.8 KiB
JavaScript

// Pure function retained from the supplied Meeus / NOAA implementation.
// Arguments: UTC Unix milliseconds, degrees latitude, degrees longitude.
const RAD=Math.PI/180,DAY_MS=86400000;
const mod=(x,n)=>((x%n)+n)%n,clamp=(x,a,b)=>Math.max(a,Math.min(b,x));
export function solarPosition(ms, lat, lon) {
const jd = ms / DAY_MS + 2440587.5, t = (jd - 2451545) / 36525;
const L = mod(280.46646 + t * (36000.76983 + t * .0003032), 360) * RAD;
const M = (357.52911 + t * (35999.05029 - .0001537 * t)) * RAD;
const e = .016708634 - t * (.000042037 + .0000001267 * t);
const C = Math.sin(M) * (1.914602 - t * (.004817 + .000014 * t)) + Math.sin(2 * M) * (.019993 - .000101 * t) + Math.sin(3 * M) * .000289;
const omega = (125.04 - 1934.136 * t) * RAD;
const lambda = L + (C - .00569 - .00478 * Math.sin(omega)) * RAD;
const mean = 23 + (26 + (21.448 - t * (46.815 + t * (.00059 - t * .001813))) / 60) / 60;
const obliq = (mean + .00256 * Math.cos(omega)) * RAD;
const dec = Math.asin(Math.sin(obliq) * Math.sin(lambda));
const y = Math.tan(obliq / 2) ** 2;
const eq = 4 / RAD * (y * Math.sin(2 * L) - 2 * e * Math.sin(M) + 4 * e * y * Math.sin(M) * Math.cos(2 * L) - .5 * y * y * Math.sin(4 * L) - 1.25 * e * e * Math.sin(2 * M));
const solarMinutes = mod(mod(ms, DAY_MS) / 60000 + eq + 4 * lon, 1440);
const H = (solarMinutes / 4 - 180) * RAD, phi = lat * RAD;
const elevation = Math.asin(clamp(Math.sin(phi) * Math.sin(dec) + Math.cos(phi) * Math.cos(dec) * Math.cos(H), -1, 1)) / RAD;
const azimuth = mod(Math.atan2(Math.sin(H), Math.cos(H) * Math.sin(phi) - Math.tan(dec) * Math.cos(phi)) / RAD + 180, 360);
return { elevation, azimuth, declination: dec / RAD, equationOfTime: eq };
}