'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var base = require('./base.cjs'); var solar = require('./solar.cjs'); /** * @copyright 2013 Sonia Keys * @copyright 2016 commenthol * @license MIT * @module solstice */ const { abs, cos, sin } = Math; const D2R = Math.PI / 180; // table 27.a - for years from -1000 to +1000 const mc0 = [1721139.29189, 365242.13740, 0.06134, 0.00111, -0.00071]; const jc0 = [1721233.25401, 365241.72562, -0.05323, 0.00907, 0.00025]; const sc0 = [1721325.70455, 365242.49558, -0.11677, -0.00297, 0.00074]; const dc0 = [1721414.39987, 365242.88257, -0.00769, -0.00933, -0.00006]; // table 27.b - for years from +1000 to +3000 const mc2 = [2451623.80984, 365242.37404, 0.05169, -0.00411, -0.00057]; const jc2 = [2451716.56767, 365241.62603, 0.00325, 0.00888, -0.00030]; const sc2 = [2451810.21715, 365242.01767, -0.11575, 0.00337, 0.00078]; const dc2 = [2451900.05952, 365242.74049, -0.06223, -0.00823, 0.00032]; // table 27.c const terms = (function () { const term = [ [485, 324.96, 1934.136], [203, 337.23, 32964.467], [199, 342.08, 20.186], [182, 27.85, 445267.112], [156, 73.14, 45036.886], [136, 171.52, 22518.443], [77, 222.54, 65928.934], [74, 296.72, 3034.906], [70, 243.58, 9037.513], [58, 119.81, 33718.147], [52, 297.17, 150.678], [50, 21.02, 2281.226], [45, 247.54, 29929.562], [44, 325.15, 31555.956], [29, 60.93, 4443.417], [18, 155.12, 67555.328], [17, 288.79, 4562.452], [16, 198.04, 62894.029], [14, 199.76, 31436.921], [12, 95.39, 14577.848], [12, 287.11, 31931.756], [12, 320.81, 34777.259], [9, 227.73, 1222.114], [8, 15.45, 16859.074] ]; return term.map((t) => { return { a: t[0], b: t[1], c: t[2] } }) })(); /** * March returns the JDE of the March equinox for the given year. * * Results are valid for the years -1000 to +3000. * * Accuracy is within one minute of time for the years 1951-2050. * @param {Number} y - (int) year * @returns {Number} JDE */ function march (y) { if (y < 1000) { return eq(y, mc0) } return eq(y - 2000, mc2) } /** * June returns the JDE of the June solstice for the given year. * * Results are valid for the years -1000 to +3000. * * Accuracy is within one minute of time for the years 1951-2050. * @param {Number} y - (int) year * @returns {Number} JDE */ function june (y) { if (y < 1000) { return eq(y, jc0) } return eq(y - 2000, jc2) } /** * September returns the JDE of the September equinox for the given year. * * Results are valid for the years -1000 to +3000. * * Accuracy is within one minute of time for the years 1951-2050. * @param {Number} y - (int) year * @returns {Number} JDE */ function september (y) { if (y < 1000) { return eq(y, sc0) } return eq(y - 2000, sc2) } /** * December returns the JDE of the December solstice for a given year. * * Results are valid for the years -1000 to +3000. * * Accuracy is within one minute of time for the years 1951-2050. * @param {Number} y - (int) year * @returns {Number} JDE */ function december (y) { if (y < 1000) { return eq(y, dc0) } return eq(y - 2000, dc2) } /** * Fast calculation of solstices/ equinoxes * Accuracy is within one minute of time for the years 1951-2050. * * @param {Number} y - (int) year * @param {Array} c - term from table 27.a / 27.b * @returns {Number} JDE */ function eq (y, c) { const J0 = base["default"].horner(y * 0.001, c); const T = base["default"].J2000Century(J0); const W = 35999.373 * D2R * T - 2.47 * D2R; const Δλ = 1 + 0.0334 * cos(W) + 0.0007 * cos(2 * W); let S = 0; for (let i = terms.length - 1; i >= 0; i--) { const t = terms[i]; S += t.a * cos((t.b + t.c * T) * D2R); } return J0 + 0.00001 * S / Δλ } /** * March2 returns a more accurate JDE of the March equinox. * * Result is accurate to one second of time. * * @param {Number} year - (int) year * @param {planetposition.Planet} planet - must be a V87Planet object representing Earth, obtained with * the package planetposition * @returns {Number} JDE */ function march2 (year, planet) { return longitude(year, planet, 0) } /** * June2 returns a more accurate JDE of the June solstice. * * Result is accurate to one second of time. * * @param {Number} year - (int) year * @param {planetposition.Planet} planet - must be a V87Planet object representing Earth, obtained with * the package planetposition * @returns {Number} JDE */ function june2 (year, planet) { return longitude(year, planet, Math.PI / 2) } /** * September2 returns a more accurate JDE of the September equinox. * * Result is accurate to one second of time. * * @param {Number} year - (int) year * @param {planetposition.Planet} planet - must be a V87Planet object representing Earth, obtained with * the package planetposition * @returns {Number} JDE */ function september2 (year, planet) { return longitude(year, planet, Math.PI) } /** * December2 returns a more accurate JDE of the December solstice. * * Result is accurate to one second of time. * * @param {Number} year - (int) year * @param {planetposition.Planet} planet - must be a V87Planet object representing Earth, obtained with * the package planetposition * @returns {Number} JDE */ function december2 (year, planet) { return longitude(year, planet, Math.PI * 3 / 2) } /** * Longitude returns the JDE for a given `year`, VSOP87 Planet `planet` at a * given geocentric solar longitude `lon` * @param {Number} year - (int) * @param {planetposition.Planet} planet * @param {Number} lon - geocentric solar longitude in radians * @returns {Number} JDE */ function longitude (year, planet, lon) { let c; let ct; if (year < 1000) { ct = [mc0, jc0, sc0, dc0]; } else { ct = [mc2, jc2, sc2, dc2]; year -= 2000; } lon = lon % (Math.PI * 2); if (lon < Math.PI / 2) { c = ct[0]; } else if (lon < Math.PI) { c = ct[1]; } else if (lon < Math.PI * 3 / 2) { c = ct[2]; } else { c = ct[3]; } return eq2(year, planet, lon, c) } /** * Accurate calculation of solstices/ equinoxes * Result is accurate to one second of time. * * @param {Number} year - (int) year * @param {planetposition.Planet} planet - vsop87 planet * @param {Number} lon - longitude in radians * @param {Array} c - term from table 27.a / 27.b * @returns {Number} JDE */ function eq2 (year, planet, lon, c) { let J0 = base["default"].horner(year * 0.001, c); for (;;) { const a = solar["default"].apparentVSOP87(planet, J0); const c = 58 * sin(lon - a.lon); // (27.1) p. 180 J0 += c; if (abs(c) < 0.000005) { break } } return J0 } var solstice = { march, june, september, december, march2, june2, september2, december2, longitude }; exports.december = december; exports.december2 = december2; exports["default"] = solstice; exports.june = june; exports.june2 = june2; exports.longitude = longitude; exports.march = march; exports.march2 = march2; exports.september = september; exports.september2 = september2;