276 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			276 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
'use strict';
 | 
						||
 | 
						||
Object.defineProperty(exports, '__esModule', { value: true });
 | 
						||
 | 
						||
var base = require('./base.cjs');
 | 
						||
var moonphase = require('./moonphase.cjs');
 | 
						||
 | 
						||
/**
 | 
						||
 * @copyright 2013 Sonia Keys
 | 
						||
 * @copyright 2016 commenthol
 | 
						||
 * @license MIT
 | 
						||
 * @module eclipse
 | 
						||
 */
 | 
						||
 | 
						||
/**
 | 
						||
 * @private
 | 
						||
 */
 | 
						||
const g = function (k, jm, c1, c2) { // (k, jm, c1, c2 float64)  (eclipse bool, jdeMax, γ, u, Mʹ float64)
 | 
						||
  const ck = 1 / 1236.85;
 | 
						||
  const p = Math.PI / 180;
 | 
						||
  const T = k * ck;
 | 
						||
  const F = base["default"].horner(T, 160.7108 * p, 390.67050284 * p / ck,
 | 
						||
    -0.0016118 * p, -0.00000227 * p, 0.000000011 * p);
 | 
						||
  if (Math.abs(Math.sin(F)) > 0.36) {
 | 
						||
    return [false] // no eclipse
 | 
						||
  }
 | 
						||
  const eclipse = true;
 | 
						||
  const E = base["default"].horner(T, 1, -0.002516, -0.0000074);
 | 
						||
  const M = base["default"].horner(T, 2.5534 * p, 29.1053567 * p / ck,
 | 
						||
    -0.0000014 * p, -0.00000011 * p);
 | 
						||
  const Mʹ = base["default"].horner(T, 201.5643 * p, 385.81693528 * p / ck,
 | 
						||
    0.0107582 * p, 0.00001238 * p, -0.000000058 * p);
 | 
						||
  const Ω = base["default"].horner(T, 124.7746 * p, -1.56375588 * p / ck,
 | 
						||
    0.0020672 * p, 0.00000215 * p);
 | 
						||
  const sΩ = Math.sin(Ω);
 | 
						||
  const F1 = F - 0.02665 * p * sΩ;
 | 
						||
  const A1 = base["default"].horner(T, 299.77 * p, 0.107408 * p / ck, -0.009173 * p);
 | 
						||
  // (54.1) p. 380
 | 
						||
  const jdeMax = jm +
 | 
						||
    c1 * Math.sin(Mʹ) +
 | 
						||
    c2 * Math.sin(M) * E +
 | 
						||
    0.0161 * Math.sin(2 * Mʹ) +
 | 
						||
    -0.0097 * Math.sin(2 * F1) +
 | 
						||
    0.0073 * Math.sin(Mʹ - M) * E +
 | 
						||
    -0.005 * Math.sin(Mʹ + M) * E +
 | 
						||
    -0.0023 * Math.sin(Mʹ - 2 * F1) +
 | 
						||
    0.0021 * Math.sin(2 * M) * E +
 | 
						||
    0.0012 * Math.sin(Mʹ + 2 * F1) +
 | 
						||
    0.0006 * Math.sin(2 * Mʹ + M) * E +
 | 
						||
    -0.0004 * Math.sin(3 * Mʹ) +
 | 
						||
    -0.0003 * Math.sin(M + 2 * F1) * E +
 | 
						||
    0.0003 * Math.sin(A1) +
 | 
						||
    -0.0002 * Math.sin(M - 2 * F1) * E +
 | 
						||
    -0.0002 * Math.sin(2 * Mʹ - M) * E +
 | 
						||
    -0.0002 * sΩ;
 | 
						||
  const P = 0.207 * Math.sin(M) * E +
 | 
						||
    0.0024 * Math.sin(2 * M) * E +
 | 
						||
    -0.0392 * Math.sin(Mʹ) +
 | 
						||
    0.0116 * Math.sin(2 * Mʹ) +
 | 
						||
    -0.0073 * Math.sin(Mʹ + M) * E +
 | 
						||
    0.0067 * Math.sin(Mʹ - M) * E +
 | 
						||
    0.0118 * Math.sin(2 * F1);
 | 
						||
  const Q = 5.2207 +
 | 
						||
    -0.0048 * Math.cos(M) * E +
 | 
						||
    0.002 * Math.cos(2 * M) * E +
 | 
						||
    -0.3299 * Math.cos(Mʹ) +
 | 
						||
    -0.006 * Math.cos(Mʹ + M) * E +
 | 
						||
    0.0041 * Math.cos(Mʹ - M) * E;
 | 
						||
  const [sF1, cF1] = base["default"].sincos(F1);
 | 
						||
  const W = Math.abs(cF1);
 | 
						||
  const γ = (P * cF1 + Q * sF1) * (1 - 0.0048 * W);
 | 
						||
  const u = 0.0059 +
 | 
						||
    0.0046 * Math.cos(M) * E +
 | 
						||
    -0.0182 * Math.cos(Mʹ) +
 | 
						||
    0.0004 * Math.cos(2 * Mʹ) +
 | 
						||
    -0.0005 * Math.cos(M + Mʹ);
 | 
						||
  return [eclipse, jdeMax, γ, u, Mʹ] // (eclipse bool, jdeMax, γ, u, Mʹ float64)
 | 
						||
};
 | 
						||
 | 
						||
/**
 | 
						||
 * Eclipse type identifiers returned from Solar and Lunar.
 | 
						||
 */
 | 
						||
const TYPE = {
 | 
						||
  None: 0,
 | 
						||
  Partial: 1, // for solar eclipses
 | 
						||
  Annular: 2, // solar
 | 
						||
  AnnularTotal: 3, // solar
 | 
						||
  Penumbral: 4, // for lunar eclipses
 | 
						||
  Umbral: 5, // lunar
 | 
						||
  Total: 6 // solar or lunar
 | 
						||
};
 | 
						||
 | 
						||
/**
 | 
						||
 * Snap returns k at specified quarter q nearest year y.
 | 
						||
 * Cut and paste from moonphase.  Time corresponding to k needed in these
 | 
						||
 * algorithms but otherwise not meaningful enough to export from moonphase.
 | 
						||
 */
 | 
						||
const snap = function (y, q) { // (y, q float64)  float64
 | 
						||
  const k = (y - 2000) * 12.3685; // (49.2) p. 350
 | 
						||
  return Math.floor(k - q + 0.5) + q
 | 
						||
};
 | 
						||
 | 
						||
/**
 | 
						||
 * Solar computes quantities related to solar eclipses.
 | 
						||
 *
 | 
						||
 * Argument year is a decimal year specifying a date.
 | 
						||
 *
 | 
						||
 * eclipseType will be None, Partial, Annular, AnnularTotal, or Total.
 | 
						||
 * If None, none of the other return values may be meaningful.
 | 
						||
 *
 | 
						||
 * central is true if the center of the eclipse shadow touches the Earth.
 | 
						||
 *
 | 
						||
 * jdeMax is the jde when the center of the eclipse shadow is closest to the
 | 
						||
 * Earth center, in a plane through the center of the Earth.
 | 
						||
 *
 | 
						||
 * γ is the distance from the eclipse shadow center to the Earth center
 | 
						||
 * at time jdeMax.
 | 
						||
 *
 | 
						||
 * u is the radius of the Moon's umbral cone in the plane of the Earth.
 | 
						||
 *
 | 
						||
 * p is the radius of the penumbral cone.
 | 
						||
 *
 | 
						||
 * mag is eclipse magnitude for partial eclipses.  It is not valid for other
 | 
						||
 * eclipse types.
 | 
						||
 *
 | 
						||
 * γ, u, and p are in units of equatorial Earth radii.
 | 
						||
 */
 | 
						||
function solar (year) { // (year float64)  (eclipseType int, central bool, jdeMax, γ, u, p, mag float64)
 | 
						||
  let eclipseType = TYPE.None;
 | 
						||
  let mag;
 | 
						||
 | 
						||
  const [e, jdeMax, γ, u, _] = g(snap(year, 0), moonphase["default"].meanNew(year), -0.4075, 0.1721); // eslint-disable-line no-unused-vars
 | 
						||
 | 
						||
  const p = u + 0.5461;
 | 
						||
  if (!e) {
 | 
						||
    return { type: eclipseType } // no eclipse
 | 
						||
  }
 | 
						||
  const aγ = Math.abs(γ);
 | 
						||
  if (aγ > 1.5433 + u) {
 | 
						||
    return { type: eclipseType } // no eclipse
 | 
						||
  }
 | 
						||
  const central = aγ < 0.9972; // eclipse center touches Earth
 | 
						||
 | 
						||
  if (!central) {
 | 
						||
    eclipseType = TYPE.Partial; // most common case
 | 
						||
    if (aγ < 1.026) { // umbral cone may touch earth
 | 
						||
      if (aγ < 0.9972 + Math.abs(u)) { // total or annular
 | 
						||
        eclipseType = TYPE.Total; // report total in both cases
 | 
						||
      }
 | 
						||
    }
 | 
						||
  } else if (u < 0) {
 | 
						||
    eclipseType = TYPE.Total;
 | 
						||
  } else if (u > 0.0047) {
 | 
						||
    eclipseType = TYPE.Annular;
 | 
						||
  } else {
 | 
						||
    const ω = 0.00464 * Math.sqrt(1 - γ * γ);
 | 
						||
    if (u < ω) {
 | 
						||
      eclipseType = TYPE.AnnularTotal;
 | 
						||
    } else {
 | 
						||
      eclipseType = TYPE.Annular;
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  if (eclipseType === TYPE.Partial) {
 | 
						||
    // (54.2) p. 382
 | 
						||
    mag = (1.5433 + u - aγ) / (0.5461 + 2 * u);
 | 
						||
  }
 | 
						||
 | 
						||
  return {
 | 
						||
    type: eclipseType,
 | 
						||
    central,
 | 
						||
    jdeMax,
 | 
						||
    magnitude: mag,
 | 
						||
    distance: γ,
 | 
						||
    umbral: u,
 | 
						||
    penumbral: p
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
/**
 | 
						||
 * Lunar computes quantities related to lunar eclipses.
 | 
						||
 *
 | 
						||
 * Argument year is a decimal year specifying a date.
 | 
						||
 *
 | 
						||
 * eclipseType will be None, Penumbral, Umbral, or Total.
 | 
						||
 * If None, none of the other return values may be meaningful.
 | 
						||
 *
 | 
						||
 * jdeMax is the jde when the center of the eclipse shadow is closest to the
 | 
						||
 * Moon center, in a plane through the center of the Moon.
 | 
						||
 *
 | 
						||
 * γ is the distance from the eclipse shadow center to the moon center
 | 
						||
 * at time jdeMax.
 | 
						||
 *
 | 
						||
 * σ is the radius of the umbral cone in the plane of the Moon.
 | 
						||
 *
 | 
						||
 * ρ is the radius of the penumbral cone.
 | 
						||
 *
 | 
						||
 * mag is eclipse magnitude.
 | 
						||
 *
 | 
						||
 * sd- return values are semidurations of the phases of the eclipse, in days.
 | 
						||
 *
 | 
						||
 * γ, σ, and ρ are in units of equatorial Earth radii.
 | 
						||
 */
 | 
						||
function lunar (year) { // (year float64)  (eclipseType int, jdeMax, γ, ρ, σ, mag, sdTotal, sdPartial, sdPenumbral float64)
 | 
						||
  let eclipseType = TYPE.None;
 | 
						||
  let mag;
 | 
						||
  let sdTotal;
 | 
						||
  let sdPartial;
 | 
						||
  let sdPenumbral;
 | 
						||
 | 
						||
  const [e, jdeMax, γ, u, Mʹ] = g(snap(year, 0.5),
 | 
						||
    moonphase["default"].meanFull(year), -0.4065, 0.1727);
 | 
						||
  if (!e) {
 | 
						||
    return { type: eclipseType } // no eclipse
 | 
						||
  }
 | 
						||
  const ρ = 1.2848 + u;
 | 
						||
  const σ = 0.7403 - u;
 | 
						||
  const aγ = Math.abs(γ);
 | 
						||
  mag = (1.0128 - u - aγ) / 0.545; // (54.3) p. 382
 | 
						||
 | 
						||
  if (mag > 1) {
 | 
						||
    eclipseType = TYPE.Total;
 | 
						||
  } else if (mag > 0) {
 | 
						||
    eclipseType = TYPE.Umbral;
 | 
						||
  } else {
 | 
						||
    mag = (1.5573 + u - aγ) / 0.545; // (54.4) p. 382
 | 
						||
    if (mag < 0) {
 | 
						||
      return { type: eclipseType } // no eclipse
 | 
						||
    }
 | 
						||
    eclipseType = TYPE.Penumbral;
 | 
						||
  }
 | 
						||
 | 
						||
  const p = 1.0128 - u;
 | 
						||
  const t = 0.4678 - u;
 | 
						||
  const n = 0.5458 + 0.04 * Math.cos(Mʹ);
 | 
						||
  const γ2 = γ * γ;
 | 
						||
 | 
						||
  /* eslint-disable no-fallthrough */
 | 
						||
  switch (eclipseType) {
 | 
						||
    case TYPE.Total: {
 | 
						||
      sdTotal = Math.sqrt(t * t - γ2) / n / 24;
 | 
						||
    }
 | 
						||
    case TYPE.Umbral: {
 | 
						||
      sdPartial = Math.sqrt(p * p - γ2) / n / 24;
 | 
						||
    }
 | 
						||
    default: {
 | 
						||
      const h = 1.5573 + u;
 | 
						||
      sdPenumbral = Math.sqrt(h * h - γ2) / n / 24;
 | 
						||
    }
 | 
						||
  }
 | 
						||
  /* eslint-enable */
 | 
						||
 | 
						||
  return {
 | 
						||
    type: eclipseType,
 | 
						||
    jdeMax,
 | 
						||
    magnitude: mag,
 | 
						||
    distance: γ,
 | 
						||
    umbral: σ,
 | 
						||
    penumbral: ρ,
 | 
						||
    sdTotal,
 | 
						||
    sdPartial,
 | 
						||
    sdPenumbral
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
var eclipse = {
 | 
						||
  TYPE,
 | 
						||
  solar,
 | 
						||
  lunar
 | 
						||
};
 | 
						||
 | 
						||
exports.TYPE = TYPE;
 | 
						||
exports["default"] = eclipse;
 | 
						||
exports.lunar = lunar;
 | 
						||
exports.solar = solar;
 |