UNPKG

7.78 kBJavaScriptView Raw
1/**
2 * @copyright 2013 Sonia Keys
3 * @copyright 2016 commenthol
4 * @license MIT
5 * @module eclipse
6 */
7/**
8 * Eclipse: Chapter 54, Eclipses.
9 */
10import base from './base';
11import moonphase from './moonphase';
12
13/**
14 * @private
15 */
16var g = function g(k, jm, c1, c2) {
17 // (k, jm, c1, c2 float64) (eclipse bool, jdeMax, γ, u, Mʹ float64)
18 var ck = 1 / 1236.85;
19 var p = Math.PI / 180;
20 var T = k * ck;
21 var F = base.horner(T, 160.7108 * p, 390.67050284 * p / ck, -0.0016118 * p, -0.00000227 * p, 0.000000011 * p);
22 if (Math.abs(Math.sin(F)) > 0.36) {
23 return; // no eclipse
24 }
25 var eclipse = true;
26 var E = base.horner(T, 1, -0.002516, -0.0000074);
27 var M = base.horner(T, 2.5534 * p, 29.1053567 * p / ck, -0.0000014 * p, -0.00000011 * p);
28 var Mʹ = base.horner(T, 201.5643 * p, 385.81693528 * p / ck, 0.0107582 * p, 0.00001238 * p, -0.000000058 * p);
29 var Ω = base.horner(T, 124.7746 * p, -1.56375588 * p / ck, 0.0020672 * p, 0.00000215 * p);
30 var sΩ = Math.sin(Ω);
31 var F1 = F - 0.02665 * p * sΩ;
32 var A1 = base.horner(T, 299.77 * p, 0.107408 * p / ck, -0.009173 * p);
33 // (54.1) p. 380
34 var 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Ω;
35 var 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);
36 var 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;
37
38 var _base$sincos = base.sincos(F1),
39 sF1 = _base$sincos[0],
40 cF1 = _base$sincos[1];
41
42 var W = Math.abs(cF1);
43 var γ = (P * cF1 + Q * sF1) * (1 - 0.0048 * W);
44 var 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ʹ);
45 return [eclipse, jdeMax, γ, u, Mʹ]; // (eclipse bool, jdeMax, γ, u, Mʹ float64)
46};
47
48/**
49 * Eclipse type identifiers returned from Solar and Lunar.
50 */
51export var TYPE = {
52 None: 0,
53 Partial: 1, // for solar eclipses
54 Annular: 2, // solar
55 AnnularTotal: 3, // solar
56 Penumbral: 4, // for lunar eclipses
57 Umbral: 5, // lunar
58 Total: 6 // solar or lunar
59
60
61 /**
62 * Snap returns k at specified quarter q nearest year y.
63 * Cut and paste from moonphase. Time corresponding to k needed in these
64 * algorithms but otherwise not meaningful enough to export from moonphase.
65 */
66};var snap = function snap(y, q) {
67 // (y, q float64) float64
68 var k = (y - 2000) * 12.3685; // (49.2) p. 350
69 return Math.floor(k - q + 0.5) + q;
70};
71
72/**
73 * Solar computes quantities related to solar eclipses.
74 *
75 * Argument year is a decimal year specifying a date.
76 *
77 * eclipseType will be None, Partial, Annular, AnnularTotal, or Total.
78 * If None, none of the other return values may be meaningful.
79 *
80 * central is true if the center of the eclipse shadow touches the Earth.
81 *
82 * jdeMax is the jde when the center of the eclipse shadow is closest to the
83 * Earth center, in a plane through the center of the Earth.
84 *
85 * γ is the distance from the eclipse shadow center to the Earth center
86 * at time jdeMax.
87 *
88 * u is the radius of the Moon's umbral cone in the plane of the Earth.
89 *
90 * p is the radius of the penumbral cone.
91 *
92 * mag is eclipse magnitude for partial eclipses. It is not valid for other
93 * eclipse types.
94 *
95 * γ, u, and p are in units of equatorial Earth radii.
96 */
97export function solar(year) {
98 // (year float64) (eclipseType int, central bool, jdeMax, γ, u, p, mag float64)
99 var eclipseType = TYPE.None;
100 var mag = void 0;
101
102 var _g = g(snap(year, 0), moonphase.meanNew(year), -0.4075, 0.1721),
103 e = _g[0],
104 jdeMax = _g[1],
105 γ = _g[2],
106 u = _g[3],
107 _ = _g[4]; // eslint-disable-line no-unused-vars
108
109 var p = u + 0.5461;
110 if (!e) {
111 return { type: eclipseType // no eclipse
112 };
113 }
114 var aγ = Math.abs(γ);
115 if (aγ > 1.5433 + u) {
116 return { type: eclipseType // no eclipse
117 };
118 }
119 var central = aγ < 0.9972; // eclipse center touches Earth
120
121 if (!central) {
122 eclipseType = TYPE.Partial; // most common case
123 if (aγ < 1.026) {
124 // umbral cone may touch earth
125 if (aγ < 0.9972 + Math.abs(u)) {
126 // total or annular
127 eclipseType = TYPE.Total; // report total in both cases
128 }
129 }
130 } else if (u < 0) {
131 eclipseType = TYPE.Total;
132 } else if (u > 0.0047) {
133 eclipseType = TYPE.Annular;
134 } else {
135 var ω = 0.00464 * Math.sqrt(1 - γ * γ);
136 if (u < ω) {
137 eclipseType = TYPE.AnnularTotal;
138 } else {
139 eclipseType = TYPE.Annular;
140 }
141 }
142
143 if (eclipseType === TYPE.Partial) {
144 // (54.2) p. 382
145 mag = (1.5433 + u - aγ) / (0.5461 + 2 * u);
146 }
147
148 return {
149 type: eclipseType,
150 central: central,
151 jdeMax: jdeMax,
152 magnitude: mag,
153 distance: γ,
154 umbral: u,
155 penumbral: p
156 };
157}
158
159/**
160 * Lunar computes quantities related to lunar eclipses.
161 *
162 * Argument year is a decimal year specifying a date.
163 *
164 * eclipseType will be None, Penumbral, Umbral, or Total.
165 * If None, none of the other return values may be meaningful.
166 *
167 * jdeMax is the jde when the center of the eclipse shadow is closest to the
168 * Moon center, in a plane through the center of the Moon.
169 *
170 * γ is the distance from the eclipse shadow center to the moon center
171 * at time jdeMax.
172 *
173 * σ is the radius of the umbral cone in the plane of the Moon.
174 *
175 * ρ is the radius of the penumbral cone.
176 *
177 * mag is eclipse magnitude.
178 *
179 * sd- return values are semidurations of the phases of the eclipse, in days.
180 *
181 * γ, σ, and ρ are in units of equatorial Earth radii.
182 */
183export function lunar(year) {
184 // (year float64) (eclipseType int, jdeMax, γ, ρ, σ, mag, sdTotal, sdPartial, sdPenumbral float64)
185 var eclipseType = TYPE.None;
186 var mag = void 0;
187 var sdTotal = void 0;
188 var sdPartial = void 0;
189 var sdPenumbral = void 0;
190
191 var _g2 = g(snap(year, 0.5), moonphase.meanFull(year), -0.4065, 0.1727),
192 e = _g2[0],
193 jdeMax = _g2[1],
194 γ = _g2[2],
195 u = _g2[3],
196 Mʹ = _g2[4];
197
198 if (!e) {
199 return { type: eclipseType // no eclipse
200 };
201 }
202 var ρ = 1.2848 + u;
203 var σ = 0.7403 - u;
204 var aγ = Math.abs(γ);
205 mag = (1.0128 - u - aγ) / 0.545; // (54.3) p. 382
206
207 if (mag > 1) {
208 eclipseType = TYPE.Total;
209 } else if (mag > 0) {
210 eclipseType = TYPE.Umbral;
211 } else {
212 mag = (1.5573 + u - aγ) / 0.545; // (54.4) p. 382
213 if (mag < 0) {
214 return; // no eclipse
215 }
216 eclipseType = TYPE.Penumbral;
217 }
218
219 var p = 1.0128 - u;
220 var t = 0.4678 - u;
221 var n = 0.5458 + 0.04 * Math.cos(Mʹ);
222 var γ2 = γ * γ;
223
224 /* eslint-disable no-fallthrough */
225 switch (eclipseType) {
226 case TYPE.Total:
227 {
228 sdTotal = Math.sqrt(t * t - γ2) / n / 24;
229 }
230 case TYPE.Umbral:
231 {
232 sdPartial = Math.sqrt(p * p - γ2) / n / 24;
233 }
234 default:
235 {
236 var h = 1.5573 + u;
237 sdPenumbral = Math.sqrt(h * h - γ2) / n / 24;
238 }
239 }
240 /* eslint-enable */
241
242 return {
243 type: eclipseType,
244 jdeMax: jdeMax,
245 magnitude: mag,
246 distance: γ,
247 umbral: σ,
248 penumbral: ρ,
249 sdTotal: sdTotal,
250 sdPartial: sdPartial,
251 sdPenumbral: sdPenumbral
252 };
253}
254
255export default {
256 TYPE: TYPE,
257 solar: solar,
258 lunar: lunar
259};
\No newline at end of file