UNPKG

17.4 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.Moon = undefined;
7
8var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
9
10var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); /**
11 * @copyright 2013 Sonia Keys
12 * @copyright 2016 commenthol
13 * @license MIT
14 * @module moon
15 */
16/**
17 * Moon: Chapter 53, Ephemeris for Physical Observations of the Moon.
18 *
19 * Incomplete. Topocentric functions are commented out for lack of test data.
20 */
21
22// import parallax from './parallax'
23
24// import planetposition from './planetposition'
25
26
27exports.physical = physical;
28exports.sunAltitude = sunAltitude;
29exports.sunrise = sunrise;
30exports.sunset = sunset;
31
32var _base = require('./base');
33
34var _base2 = _interopRequireDefault(_base);
35
36var _coord = require('./coord');
37
38var _coord2 = _interopRequireDefault(_coord);
39
40var _moonposition = require('./moonposition');
41
42var _moonposition2 = _interopRequireDefault(_moonposition);
43
44var _nutation = require('./nutation');
45
46var _nutation2 = _interopRequireDefault(_nutation);
47
48var _solar = require('./solar');
49
50var _solar2 = _interopRequireDefault(_solar);
51
52function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
53
54function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
55
56var p = Math.PI / 180;
57var _I = 1.54242 * p; // IAU value of inclination of mean lunar equator
58
59var _base$sincos = _base2.default.sincos(_I),
60 _base$sincos2 = _slicedToArray(_base$sincos, 2),
61 sI = _base$sincos2[0],
62 cI = _base$sincos2[1];
63
64/**
65 * Physical returns quantities useful for physical observation of the Moon.
66 *
67 * Returned l, b are librations in selenographic longitude and latitude.
68 * They represent combined optical and physical librations. Topocentric
69 * librations are not considered.
70 *
71 * Returned P is the the position angle of the Moon's axis of rotation.
72 *
73 * Returned l0, b0 are the selenographic coordinates of the Sun.
74 *
75 * Returned values all in radians.
76
77 * @param {number} jde - Julian ephemeris day
78 * @param {planetposition.Planet} earth - VSOP87 Planet Earth
79 * @return {Array}
80 * {base.Coord} cMoon - selenographic longitude, latitude of the Moon
81 * {number} P - position angle of the Moon's axis of rotation
82 * {base.Coord} cSun - selenographic longitude, latitude of the Sun.
83 */
84
85
86function physical(jde, earth) {
87 var _moonposition$positio = _moonposition2.default.position(jde),
88 lon = _moonposition$positio.lon,
89 lat = _moonposition$positio.lat,
90 range = _moonposition$positio.range; // (λ without nutation)
91 // [λ, β, Δ]
92
93
94 var m = new Moon(jde);
95
96 var _m$lib = m.lib(lon, lat),
97 _m$lib2 = _slicedToArray(_m$lib, 2),
98 l = _m$lib2[0],
99 b = _m$lib2[1];
100
101 var P = m.pa(lon, lat, b);
102
103 var _m$sun = m.sun(lon, lat, range, earth),
104 _m$sun2 = _slicedToArray(_m$sun, 2),
105 l0 = _m$sun2[0],
106 b0 = _m$sun2[1];
107
108 var cMoon = new _base2.default.Coord(l, b);
109 var cSun = new _base2.default.Coord(l0, b0);
110 return [cMoon, P, cSun];
111}
112
113/**
114 * Quantities computed for a jde and used in computing return values of
115 * physical(). Computations are broken into several methods to organize
116 * the code.
117 */
118
119var Moon = exports.Moon = function () {
120 function Moon(jde) {
121 _classCallCheck(this, Moon);
122
123 this.jde = jde;
124 // Δψ, F, Ω, p. 372.0
125
126 var _nutation$nutation = _nutation2.default.nutation(jde),
127 _nutation$nutation2 = _slicedToArray(_nutation$nutation, 2),
128 Δψ = _nutation$nutation2[0],
129 Δε = _nutation$nutation2[1];
130
131 this.Δψ = Δψ;
132 var T = _base2.default.J2000Century(jde);
133 var F = this.F = _base2.default.horner(T, 93.272095 * p, 483202.0175233 * p, -0.0036539 * p, -p / 3526000, p / 863310000);
134 this.Ω = _base2.default.horner(T, 125.0445479 * p, -1934.1362891 * p, 0.0020754 * p, p / 467441, -p / 60616000);
135 // true ecliptic
136 this.ε = _nutation2.default.meanObliquity(jde) + Δε;
137 this.sε = Math.sin(this.ε);
138 this.cε = Math.cos(this.ε);
139 // ρ, σ, τ, p. 372,373
140 var D = _base2.default.horner(T, 297.8501921 * p, 445267.1114034 * p, -0.0018819 * p, p / 545868, -p / 113065000);
141 var M = _base2.default.horner(T, 357.5291092 * p, 35999.0502909 * p, -0.0001535 * p, p / 24490000);
142 var M_ = _base2.default.horner(T, 134.9633964 * p, 477198.8675055 * p, 0.0087414 * p, p / 69699, -p / 14712000);
143 var E = _base2.default.horner(T, 1, -0.002516, -0.0000074);
144 var K1 = 119.75 * p + 131.849 * p * T;
145 var K2 = 72.56 * p + 20.186 * p * T;
146 this.ρ = -0.02752 * p * Math.cos(M_) + -0.02245 * p * Math.sin(F) + 0.00684 * p * Math.cos(M_ - 2 * F) + -0.00293 * p * Math.cos(2 * F) + -0.00085 * p * Math.cos(2 * (F - D)) + -0.00054 * p * Math.cos(M_ - 2 * D) + -0.0002 * p * Math.sin(M_ + F) + -0.0002 * p * Math.cos(M_ + 2 * F) + -0.0002 * p * Math.cos(M_ - F) + 0.00014 * p * Math.cos(M_ + 2 * (F - D));
147 this.σ = -0.02816 * p * Math.sin(M_) + 0.02244 * p * Math.cos(F) + -0.00682 * p * Math.sin(M_ - 2 * F) + -0.00279 * p * Math.sin(2 * F) + -0.00083 * p * Math.sin(2 * (F - D)) + 0.00069 * p * Math.sin(M_ - 2 * D) + 0.0004 * p * Math.cos(M_ + F) + -0.00025 * p * Math.sin(2 * M_) + -0.00023 * p * Math.sin(M_ + 2 * F) + 0.0002 * p * Math.cos(M_ - F) + 0.00019 * p * Math.sin(M_ - F) + 0.00013 * p * Math.sin(M_ + 2 * (F - D)) + -0.0001 * p * Math.cos(M_ - 3 * F);
148 this.τ = 0.0252 * p * Math.sin(M) * E + 0.00473 * p * Math.sin(2 * (M_ - F)) + -0.00467 * p * Math.sin(M_) + 0.00396 * p * Math.sin(K1) + 0.00276 * p * Math.sin(2 * (M_ - D)) + 0.00196 * p * Math.sin(this.Ω) + -0.00183 * p * Math.cos(M_ - F) + 0.00115 * p * Math.sin(M_ - 2 * D) + -0.00096 * p * Math.sin(M_ - D) + 0.00046 * p * Math.sin(2 * (F - D)) + -0.00039 * p * Math.sin(M_ - F) + -0.00032 * p * Math.sin(M_ - M - D) + 0.00027 * p * Math.sin(2 * (M_ - D) - M) + 0.00023 * p * Math.sin(K2) + -0.00014 * p * Math.sin(2 * D) + 0.00014 * p * Math.cos(2 * (M_ - F)) + -0.00012 * p * Math.sin(M_ - 2 * F) + -0.00012 * p * Math.sin(2 * M_) + 0.00011 * p * Math.sin(2 * (M_ - M - D));
149 }
150
151 /**
152 * lib() curiously serves for computing both librations and solar coordinates,
153 * depending on the coordinates λ, β passed in. Quantity A not described in
154 * the book, but clearly depends on the λ, β of the current context and so
155 * does not belong in the moon struct. Instead just return it from optical
156 * and pass it along to physical.
157 */
158
159
160 _createClass(Moon, [{
161 key: 'lib',
162 value: function lib(λ, β) {
163 var _optical = this.optical(λ, β),
164 _optical2 = _slicedToArray(_optical, 3),
165 l_ = _optical2[0],
166 b_ = _optical2[1],
167 A = _optical2[2];
168
169 var _physical = this.physical(A, b_),
170 _physical2 = _slicedToArray(_physical, 2),
171 l$ = _physical2[0],
172 b$ = _physical2[1];
173
174 var l = l_ + l$;
175 if (l > Math.PI) {
176 l -= 2 * Math.PI;
177 }
178 var b = b_ + b$;
179 return [l, b];
180 }
181 }, {
182 key: 'optical',
183 value: function optical(λ, β) {
184 // (53.1) p. 372
185 var W = λ - this.Ω; // (λ without nutation)
186
187 var _base$sincos3 = _base2.default.sincos(W),
188 _base$sincos4 = _slicedToArray(_base$sincos3, 2),
189 sW = _base$sincos4[0],
190 cW = _base$sincos4[1];
191
192 var _base$sincos5 = _base2.default.sincos(β),
193 _base$sincos6 = _slicedToArray(_base$sincos5, 2),
194 sβ = _base$sincos6[0],
195 cβ = _base$sincos6[1];
196
197 var A = Math.atan2(sW * cβ * cI - sβ * sI, cW * cβ);
198 var l_ = _base2.default.pmod(A - this.F, 2 * Math.PI);
199 var b_ = Math.asin(-sW * cβ * sI - sβ * cI);
200 return [l_, b_, A];
201 }
202 }, {
203 key: 'physical',
204 value: function physical(A, b_) {
205 // (53.2) p. 373
206 var _base$sincos7 = _base2.default.sincos(A),
207 _base$sincos8 = _slicedToArray(_base$sincos7, 2),
208 sA = _base$sincos8[0],
209 cA = _base$sincos8[1];
210
211 var l$ = -this.τ + (this.ρ * cA + this.σ * sA) * Math.tan(b_);
212 var b$ = this.σ * cA - this.ρ * sA;
213 return [l$, b$];
214 }
215 }, {
216 key: 'pa',
217 value: function pa(λ, β, b) {
218 var V = this.Ω + this.Δψ + this.σ / sI;
219
220 var _base$sincos9 = _base2.default.sincos(V),
221 _base$sincos10 = _slicedToArray(_base$sincos9, 2),
222 sV = _base$sincos10[0],
223 cV = _base$sincos10[1];
224
225 var _base$sincos11 = _base2.default.sincos(_I + this.ρ),
226 _base$sincos12 = _slicedToArray(_base$sincos11, 2),
227 sIρ = _base$sincos12[0],
228 cIρ = _base$sincos12[1];
229
230 var X = sIρ * sV;
231 var Y = sIρ * cV * this.cε - cIρ * this.sε;
232 var ω = Math.atan2(X, Y);
233 var ecl = new _coord2.default.Ecliptic(λ + this.Δψ, β).toEquatorial(this.ε); // eslint-disable-line no-unused-vars
234 var P = Math.asin(Math.hypot(X, Y) * Math.cos(ecl.ra - ω) / Math.cos(b));
235 if (P < 0) {
236 P += 2 * Math.PI;
237 }
238 return P;
239 }
240 }, {
241 key: 'sun',
242 value: function sun(λ, β, Δ, earth) {
243 var _solar$apparentVSOP = _solar2.default.apparentVSOP87(earth, this.jde),
244 lon = _solar$apparentVSOP.lon,
245 lat = _solar$apparentVSOP.lat,
246 range = _solar$apparentVSOP.range; // eslint-disable-line no-unused-vars
247
248
249 var ΔR = Δ / (range * _base2.default.AU);
250 var λH = lon + Math.PI + ΔR * Math.cos(β) * Math.sin(lon - λ);
251 var βH = ΔR * β;
252 return this.lib(λH, βH);
253 }
254 }]);
255
256 return Moon;
257}();
258
259/* commented out for lack of test data
260export function Topocentric (jde, ρsφ_, ρcφ_, L) { // (jde, ρsφ_, ρcφ_, L float64) (l, b, P float64)
261 λ, β, Δ := moonposition.Position(jde) // (λ without nutation)
262 Δψ, Δε := nutation.Nutation(jde)
263 sε, cε := base.sincos(nutation.MeanObliquity(jde) + Δε)
264 α, δ := coord.EclToEq(λ+Δψ, β, sε, cε)
265 α, δ = parallax.Topocentric(α, δ, Δ/base.AU, ρsφ_, ρcφ_, L, jde)
266 λ, β = coord.EqToEcl(α, δ, sε, cε)
267 const m = newMoon(jde)
268 l, b = m.lib(λ, β)
269 P = m.pa(λ, β, b)
270 return
271}
272
273export function TopocentricCorrections (jde, b, P, φ, δ, H, π) { // (jde, b, P, φ, δ, H, π float64) (Δl, Δb, ΔP float64)
274 sφ, cφ := base.sincos(φ)
275 sH, cH := base.sincos(H)
276 sδ, cδ := base.sincos(δ)
277 const Q = Math.atan(cφ * sH / (cδ*sφ - sδ*cφ*cH))
278 const z = Math.acos(sδ*sφ + cδ*cφ*cH)
279 const π_ = π * (Math.sin(z) + 0.0084*Math.sin(2*z))
280 sQP, cQP := base.sincos(Q - P)
281 Δl = -π_ * sQP / Math.cos(b)
282 Δb = π_ * cQP
283 ΔP = Δl*Math.sin(b+Δb) - π_*Math.sin(Q)*Math.tan(δ)
284 return
285}
286*/
287
288/**
289 * SunAltitude returns altitude of the Sun above the lunar horizon.
290 *
291 * @param {base.Coords} cOnMoon - selenographic longitude and latitude of a site on the Moon
292 * @param {base.Coords} cSun - selenographic coordinates of the Sun (as returned by physical(), for example.)
293 * @return altitude in radians.
294 */
295
296
297function sunAltitude(cOnMoon, cSun) {
298 // (η, θ, l0, b0 float64) float64
299 var c0 = Math.PI / 2 - cSun.lon;
300
301 var _base$sincos13 = _base2.default.sincos(cSun.lat),
302 _base$sincos14 = _slicedToArray(_base$sincos13, 2),
303 sb0 = _base$sincos14[0],
304 cb0 = _base$sincos14[1];
305
306 var _base$sincos15 = _base2.default.sincos(cOnMoon.lat),
307 _base$sincos16 = _slicedToArray(_base$sincos15, 2),
308 sθ = _base$sincos16[0],
309 cθ = _base$sincos16[1];
310
311 return Math.asin(sb0 * sθ + cb0 * cθ * Math.sin(c0 + cOnMoon.lon));
312}
313
314/**
315 * Sunrise returns time of sunrise for a point on the Moon near the given date.
316 *
317 * @param {base.Coord} cOnMoon - selenographic longitude and latitude of a site on the Moon
318 * @param {Number} jde - Julian ephemeris day
319 * @param {planetposition.Planet} earth - VSOP87 Planet Earth
320 * @return time of sunrise as a jde nearest the given jde.
321 */
322function sunrise(cOnMoon, jde, earth) {
323 // (η, θ, jde float64, earth *pp.V87Planet) float64
324 jde -= srCorr(cOnMoon, jde, earth);
325 return jde - srCorr(cOnMoon, jde, earth);
326}
327
328/**
329 * Sunset returns time of sunset for a point on the Moon near the given date.
330 *
331 * @param {base.Coords} cOnMoon - selenographic longitude and latitude of a site on the Moon
332 * @param {Number} jde - Julian ephemeris day
333 * @param {planetposition.Planet} earth - VSOP87 Planet Earth
334 * @return time of sunset as a jde nearest the given jde.
335 */
336function sunset(cOnMoon, jde, earth) {
337 // (η, θ, jde float64, earth *pp.V87Planet) float64
338 jde += srCorr(cOnMoon, jde, earth);
339 return jde + srCorr(cOnMoon, jde, earth);
340}
341
342/**
343 * @private
344 */
345function srCorr(cOnMoon, jde, earth) {
346 var phy = physical(jde, earth);
347 var h = sunAltitude(cOnMoon, phy[2]);
348 return h / (12.19075 * p * Math.cos(cOnMoon.lat));
349}
350
351exports.default = {
352 physical: physical,
353 Moon: Moon,
354 // Topocentric,
355 // TopocentricCorrections,
356 sunAltitude: sunAltitude,
357 sunrise: sunrise,
358 sunset: sunset
359};
\No newline at end of file