@essrt/physics 11.0.0 → 11.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@essrt/physics",
3
- "version": "11.0.0",
3
+ "version": "11.0.1",
4
4
  "description": "ESSRT (Expanding Solar System Resonance Theory) physics core — pure, injectable-constants, no I/O, no globals, no DOM. The complete model incl. fitted coefficients; every published version immutably ships one recorded model identity.",
5
5
  "essrt": {
6
6
  "modelVersion": "v16.0",
@@ -373,15 +373,13 @@ function createDeepOrbitalHistory({
373
373
  return (Pi + u) * R2D;
374
374
  }
375
375
 
376
- /** Equinox-node longitudes only (J2000 ecliptic frame; projected and
377
- * general-precession forms) — the light read used for the node-rate
378
- * finite differences at store time. */
376
+ /** The three of-date longitudes whose node RATES the grid stores (the
377
+ * projected and general-precession equinox longitudes, the perihelion
378
+ * longitude of date) — read from a full sample at the probe state, so the
379
+ * rates are finite differences of exactly the stored quantities. */
379
380
  function eqLonsOnlyDeg(/** @type {number[]} */ s, /** @type {number} */ t) {
380
- const n = orbitNormal(t);
381
- const g = cross(s, n);
382
- const gn = Math.hypot(g[0], g[1], g[2]);
383
- const gu = [g[0] / gn, g[1] / gn, g[2] / gn];
384
- return { proj: Math.atan2(gu[1], gu[0]) * R2D, general: generalPrecessionLonDeg(n, gu) };
381
+ const smp = sampleAt(s, t);
382
+ return { proj: smp.equinoxLonJ2000Deg, general: smp.generalPrecessionLonDeg, peri: smp.periOfDateDeg };
385
383
  }
386
384
 
387
385
  /** One quantity bundle at time t (years from J2000) from spin axis s. */
@@ -449,6 +447,7 @@ function createDeepOrbitalHistory({
449
447
  // built on this rate (earth/year-lengths.cjs).
450
448
  generalPrecessionLonDeg: ((generalPrecessionLonDeg(n, gu) % 360) + 360) % 360,
451
449
  generalPrecessionLonRateDegPerYr: 0, // filled at store time (build's ±2.5-yr central difference)
450
+ periOfDateRateDegPerYr: 0, // filled at store time — the C1 input for periOfDateDeg (the apsidal rate of date)
452
451
  };
453
452
  }
454
453
 
@@ -488,6 +487,12 @@ function createDeepOrbitalHistory({
488
487
  // centuries with steps at the 1700/1800/1900/2000 cell edges
489
488
  // (measured; the levels were the real wobble at 100-yr resolution,
490
489
  // the staircase was this interpolation order).
490
+ // The perihelion longitude of date gets the same C1 treatment (2026-09,
491
+ // owner-found): linear interpolation of periOfDateDeg made the
492
+ // movement's year-over-year apsidal rate — the anomalistic year, the
493
+ // Prec. cell — a staircase of ±0.1 s across the 100-yr cells, reading
494
+ // 365.2596375 d at 2000.0 and 365.2596390 d at 2000.5, and the panel's
495
+ // apsidal beat 111,494 where the registry read 111,548.
491
496
  const storeWithRate = (/** @type {number} */ key, /** @type {number[]} */ sv, /** @type {number} */ tv) => {
492
497
  const smp = sampleAt(sv, tv);
493
498
  const hR = 2.5;
@@ -495,6 +500,7 @@ function createDeepOrbitalHistory({
495
500
  const lm = eqLonsOnlyDeg(rk4(sv, tv, -hR), tv - hR);
496
501
  smp.equinoxLonRateDegPerYr = (((lp.proj - lm.proj + 540) % 360) - 180) / (2 * hR);
497
502
  smp.generalPrecessionLonRateDegPerYr = (((lp.general - lm.general + 540) % 360) - 180) / (2 * hR);
503
+ smp.periOfDateRateDegPerYr = (((lp.peri - lm.peri + 540) % 360) - 180) / (2 * hR);
498
504
  grid.set(key, smp);
499
505
  };
500
506
  storeWithRate(0, s, 0);
@@ -522,7 +528,6 @@ function createDeepOrbitalHistory({
522
528
  if (!a) throw new Error(`deep-orbital-history: ${tYr} outside the built range`);
523
529
  const f = (tYr - k0) / stepYr;
524
530
  const lerp = (/** @type {number} */ x, /** @type {number} */ y) => x + (y - x) * f;
525
- const dAng = (/** @type {number} */ x, /** @type {number} */ y) => x + (((y - x + 540) % 360) - 180) * f;
526
531
  // C1 (cubic Hermite) on a wrapped angle with node rates (deg/yr) —
527
532
  // linear interpolation here made the realized equinox RATE
528
533
  // piecewise-constant per grid cell (the measured per-year
@@ -539,7 +544,8 @@ function createDeepOrbitalHistory({
539
544
  return {
540
545
  epsDeg: lerp(a.epsDeg, b.epsDeg),
541
546
  e: lerp(a.e, b.e),
542
- periOfDateDeg: ((dAng(a.periOfDateDeg, b.periOfDateDeg) % 360) + 360) % 360,
547
+ periOfDateDeg: hermiteAngle(a.periOfDateDeg, b.periOfDateDeg, a.periOfDateRateDegPerYr, b.periOfDateRateDegPerYr ?? a.periOfDateRateDegPerYr),
548
+ periOfDateRateDegPerYr: lerp(a.periOfDateRateDegPerYr, b.periOfDateRateDegPerYr ?? a.periOfDateRateDegPerYr),
543
549
  eSinPeri: lerp(a.eSinPeri, b.eSinPeri),
544
550
  eCosPeri: lerp(a.eCosPeri, b.eCosPeri),
545
551
  inclEclDeg: lerp(a.inclEclDeg, b.inclEclDeg),
@@ -71,6 +71,7 @@ export function createDeepOrbitalHistory({ zModes, zetaModes, zetaSeries, zSerie
71
71
  epsDeg: number;
72
72
  e: number;
73
73
  periOfDateDeg: number;
74
+ periOfDateRateDegPerYr: number;
74
75
  eSinPeri: number;
75
76
  eCosPeri: number;
76
77
  inclEclDeg: number;