UNPKG

6.91 kBJavaScriptView Raw
1/**
2 * @copyright 2013 Sonia Keys
3 * @copyright 2016 commenthol
4 * @license MIT
5 * @module solstice
6 */
7/**
8 * Solstice: Chapter 27: Equinoxes and Solstices.
9 */
10
11import base from './base';
12import solar from './solar';
13var abs = Math.abs,
14 cos = Math.cos,
15 sin = Math.sin;
16
17var D2R = Math.PI / 180;
18
19// table 27.a - for years from -1000 to +1000
20var mc0 = [1721139.29189, 365242.13740, 0.06134, 0.00111, -0.00071];
21var jc0 = [1721233.25401, 365241.72562, -0.05232, 0.00907, 0.00025];
22var sc0 = [1721325.70455, 365242.49558, -0.11677, -0.00297, 0.00074];
23var dc0 = [1721414.39987, 365242.88257, -0.00769, -0.00933, -0.00006];
24
25// table 27.b - for years from +1000 to +3000
26var mc2 = [2451623.80984, 365242.37404, 0.05169, -0.00411, -0.00057];
27var jc2 = [2451716.56767, 365241.62603, 0.00325, 0.00888, -0.00030];
28var sc2 = [2451810.21715, 365242.01767, -0.11575, 0.00337, 0.00078];
29var dc2 = [2451900.05952, 365242.74049, -0.06223, -0.00823, 0.00032];
30
31// table 27.c
32var terms = function () {
33 var 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]];
34 return term.map(function (t) {
35 return {
36 a: t[0],
37 b: t[1],
38 c: t[2]
39 };
40 });
41}();
42
43/**
44 * March returns the JDE of the March equinox for the given year.
45 *
46 * Results are valid for the years -1000 to +3000.
47 *
48 * Accuracy is within one minute of time for the years 1951-2050.
49 * @param {Number} y - (int) year
50 * @returns {Number} JDE
51 */
52export function march(y) {
53 if (y < 1000) {
54 return eq(y, mc0);
55 }
56 return eq(y - 2000, mc2);
57}
58
59/**
60 * June returns the JDE of the June solstice for the given year.
61 *
62 * Results are valid for the years -1000 to +3000.
63 *
64 * Accuracy is within one minute of time for the years 1951-2050.
65 * @param {Number} y - (int) year
66 * @returns {Number} JDE
67 */
68export function june(y) {
69 if (y < 1000) {
70 return eq(y, jc0);
71 }
72 return eq(y - 2000, jc2);
73}
74
75/**
76 * September returns the JDE of the September equinox for the given year.
77 *
78 * Results are valid for the years -1000 to +3000.
79 *
80 * Accuracy is within one minute of time for the years 1951-2050.
81 * @param {Number} y - (int) year
82 * @returns {Number} JDE
83 */
84export function september(y) {
85 if (y < 1000) {
86 return eq(y, sc0);
87 }
88 return eq(y - 2000, sc2);
89}
90
91/**
92 * December returns the JDE of the December solstice for a given year.
93 *
94 * Results are valid for the years -1000 to +3000.
95 *
96 * Accuracy is within one minute of time for the years 1951-2050.
97 * @param {Number} y - (int) year
98 * @returns {Number} JDE
99 */
100export function december(y) {
101 if (y < 1000) {
102 return eq(y, dc0);
103 }
104 return eq(y - 2000, dc2);
105}
106
107/**
108 * Fast calculation of solstices/ equinoxes
109 * Accuracy is within one minute of time for the years 1951-2050.
110 *
111 * @param {Number} y - (int) year
112 * @param {Array} c - term from table 27.a / 27.b
113 * @returns {Number} JDE
114 */
115function eq(y, c) {
116 var J0 = base.horner(y * 0.001, c);
117 var T = base.J2000Century(J0);
118 var W = 35999.373 * D2R * T - 2.47 * D2R;
119 var Δλ = 1 + 0.0334 * cos(W) + 0.0007 * cos(2 * W);
120 var S = 0;
121 for (var i = terms.length - 1; i >= 0; i--) {
122 var t = terms[i];
123 S += t.a * cos((t.b + t.c * T) * D2R);
124 }
125 return J0 + 0.00001 * S / Δλ;
126}
127
128/**
129 * March2 returns a more accurate JDE of the March equinox.
130 *
131 * Result is accurate to one second of time.
132 *
133 * @param {Number} year - (int) year
134 * @param {planetposition.Planet} planet - must be a V87Planet object representing Earth, obtained with
135 * the package planetposition
136 * @returns {Number} JDE
137 */
138export function march2(year, planet) {
139 return longitude(year, planet, 0);
140}
141
142/**
143 * June2 returns a more accurate JDE of the June solstice.
144 *
145 * Result is accurate to one second of time.
146 *
147 * @param {Number} year - (int) year
148 * @param {planetposition.Planet} planet - must be a V87Planet object representing Earth, obtained with
149 * the package planetposition
150 * @returns {Number} JDE
151 */
152export function june2(year, planet) {
153 return longitude(year, planet, Math.PI / 2);
154}
155
156/**
157 * September2 returns a more accurate JDE of the September equinox.
158 *
159 * Result is accurate to one second of time.
160 *
161 * @param {Number} year - (int) year
162 * @param {planetposition.Planet} planet - must be a V87Planet object representing Earth, obtained with
163 * the package planetposition
164 * @returns {Number} JDE
165 */
166export function september2(year, planet) {
167 return longitude(year, planet, Math.PI);
168}
169
170/**
171 * December2 returns a more accurate JDE of the December solstice.
172 *
173 * Result is accurate to one second of time.
174 *
175 * @param {Number} year - (int) year
176 * @param {planetposition.Planet} planet - must be a V87Planet object representing Earth, obtained with
177 * the package planetposition
178 * @returns {Number} JDE
179 */
180export function december2(year, planet) {
181 return longitude(year, planet, Math.PI * 3 / 2);
182}
183
184/**
185 * Longitude returns the JDE for a given `year`, VSOP87 Planet `planet` at a
186 * given geocentric solar longitude `lon`
187 * @param {Number} year - (int)
188 * @param {planetposition.Planet} planet
189 * @param {Number} lon - geocentric solar longitude in radians
190 * @returns {Number} JDE
191 */
192export function longitude(year, planet, lon) {
193 var c = void 0;
194 var ct = void 0;
195
196 if (year < 1000) {
197 ct = [mc0, jc0, sc0, dc0];
198 } else {
199 ct = [mc2, jc2, sc2, dc2];
200 year -= 2000;
201 }
202
203 lon = lon % (Math.PI * 2);
204
205 if (lon < Math.PI / 2) {
206 c = ct[0];
207 } else if (lon < Math.PI) {
208 c = ct[1];
209 } else if (lon < Math.PI * 3 / 2) {
210 c = ct[2];
211 } else {
212 c = ct[3];
213 }
214
215 return eq2(year, planet, lon, c);
216}
217
218/**
219 * Accurate calculation of solstices/ equinoxes
220 * Result is accurate to one second of time.
221 *
222 * @param {Number} year - (int) year
223 * @param {planetposition.Planet} planet - vsop87 planet
224 * @param {Number} lon - longitude in radians
225 * @param {Array} c - term from table 27.a / 27.b
226 * @returns {Number} JDE
227 */
228function eq2(year, planet, lon, c) {
229 var J0 = base.horner(year * 0.001, c);
230
231 for (;;) {
232 var a = solar.apparentVSOP87(planet, J0);
233 var _c = 58 * sin(lon - a.lon); // (27.1) p. 180
234 J0 += _c;
235 if (abs(_c) < 0.000005) {
236 break;
237 }
238 }
239
240 return J0;
241}
242
243export default {
244 march: march,
245 june: june,
246 september: september,
247 december: december,
248 march2: march2,
249 june2: june2,
250 september2: september2,
251 december2: december2,
252 longitude: longitude
253};
\No newline at end of file