1 | var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
2 |
|
3 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
4 |
|
5 | /**
|
6 | * @copyright 2013 Sonia Keys
|
7 | * @copyright 2016 commenthol
|
8 | * @license MIT
|
9 | * @module planetposition
|
10 | */
|
11 | /**
|
12 | * Planetposition: Chapter 32, Positions of the Planets.
|
13 | *
|
14 | * Incomplete:
|
15 | *
|
16 | * 1. The package does not implement algorithms that use appendix III,
|
17 | * but instead implements a full VSOP87 solution. I do not have a copy
|
18 | * of the supplimentary disk with appendix III in machine readable form
|
19 | * and as the appendix is rather large, retyping it by hand is problematic.
|
20 | * The full VSOP87 data set on the other hand is freely downloadable from
|
21 | * the internet, so I implement here code that can use that data directly.
|
22 | *
|
23 | * 2. The formula for accuracy of results is not implemented. It is
|
24 | * not needed for full VSOP87 solutions.
|
25 | *
|
26 | * 3. Polynomial expressions are not implemented. Again, implementation
|
27 | * would involve typing rather large tables of numbers with associated
|
28 | * risk of typographical errors.
|
29 | */
|
30 |
|
31 | import base from './base';
|
32 | import sexa from './sexagesimal';
|
33 | import coord from './coord';
|
34 | import precess from './precess';
|
35 |
|
36 | function sum(t, series) {
|
37 | var coeffs = [];
|
38 | Object.keys(series).forEach(function (x) {
|
39 | coeffs[x] = 0;
|
40 | var y = series[x].length - 1;
|
41 | for (y; y >= 0; y--) {
|
42 | var term = {
|
43 | a: series[x][y][0],
|
44 | b: series[x][y][1],
|
45 | c: series[x][y][2]
|
46 | };
|
47 | coeffs[x] += term.a * Math.cos(term.b + term.c * t);
|
48 | }
|
49 | });
|
50 | var res = base.horner(t, coeffs);
|
51 | return res;
|
52 | }
|
53 |
|
54 | export var Planet = function () {
|
55 | /**
|
56 | * VSOP87 representation of a Planet
|
57 | * @constructs Planet
|
58 | * @param {object} planet - planet data series
|
59 | * @example
|
60 | * ```js
|
61 | * // for use in browser
|
62 | * import {data} from 'astronomia'
|
63 | * const earth = new planetposition.Planet(data.vsop87Bearth)
|
64 | * ```
|
65 | */
|
66 | function Planet(planet) {
|
67 | _classCallCheck(this, Planet);
|
68 |
|
69 | if ((typeof planet === 'undefined' ? 'undefined' : _typeof(planet)) !== 'object') throw new TypeError('need planet vsop87 data');
|
70 | this.name = planet.name;
|
71 | this.series = planet;
|
72 | }
|
73 |
|
74 | /**
|
75 | * Position2000 returns ecliptic position of planets by full VSOP87 theory.
|
76 | *
|
77 | * @param {Number} jde - the date for which positions are desired.
|
78 | * @returns {base.Coord} Results are for the dynamical equinox and ecliptic J2000.
|
79 | * {Number} lon - heliocentric longitude in radians.
|
80 | * {Number} lat - heliocentric latitude in radians.
|
81 | * {Number} range - heliocentric range in AU.
|
82 | */
|
83 |
|
84 |
|
85 | Planet.prototype.position2000 = function position2000(jde) {
|
86 | var T = base.J2000Century(jde);
|
87 | var τ = T * 0.1;
|
88 | var lon = base.pmod(sum(τ, this.series.L), 2 * Math.PI);
|
89 | var lat = sum(τ, this.series.B);
|
90 | var range = sum(τ, this.series.R);
|
91 | return new base.Coord(lon, lat, range);
|
92 | };
|
93 |
|
94 | /**
|
95 | * Position returns ecliptic position of planets at equinox and ecliptic of date.
|
96 | *
|
97 | * @param {Number} jde - the date for which positions are desired.
|
98 | * @returns {base.Coord} Results are positions consistent with those from Meeus's
|
99 | * Apendix III, that is, at equinox and ecliptic of date.
|
100 | * {Number} lon - heliocentric longitude in radians.
|
101 | * {Number} lat - heliocentric latitude in radians.
|
102 | * {Number} range - heliocentric range in AU.
|
103 | */
|
104 |
|
105 |
|
106 | Planet.prototype.position = function position(jde) {
|
107 | var _position = this.position2000(jde),
|
108 | lat = _position.lat,
|
109 | lon = _position.lon,
|
110 | range = _position.range;
|
111 |
|
112 | var eclFrom = new coord.Ecliptic(lon, lat);
|
113 | var epochFrom = 2000.0;
|
114 | var epochTo = base.JDEToJulianYear(jde);
|
115 | var eclTo = precess.eclipticPosition(eclFrom, epochFrom, epochTo, 0, 0);
|
116 | return new base.Coord(eclTo.lon, eclTo.lat, range);
|
117 | };
|
118 |
|
119 | return Planet;
|
120 | }();
|
121 |
|
122 | /**
|
123 | * ToFK5 converts ecliptic longitude and latitude from dynamical frame to FK5.
|
124 | *
|
125 | * @param {Number} lon - ecliptic longitude in radians
|
126 | * @param {Number} lat - ecliptic latitude in radians
|
127 | * @param {Number} jde - Julian ephemeris day
|
128 | * @return {base.Coord}
|
129 | * {Number} lon - FK5 longitude
|
130 | * {Number} lat - FK5 latitude
|
131 | */
|
132 | export function toFK5(lon, lat, jde) {
|
133 | // formula 32.3, p. 219.
|
134 | var T = base.J2000Century(jde);
|
135 | // const Lp = lon - 1.397 * Math.PI / 180 * T - 0.00031 * Math.PI / 180 * T * T
|
136 | var Lp = lon - sexa.angleFromDeg((1.397 + 0.00031 * T) * T);
|
137 |
|
138 | var _base$sincos = base.sincos(Lp),
|
139 | sLp = _base$sincos[0],
|
140 | cLp = _base$sincos[1];
|
141 | // (32.3) p. 219
|
142 |
|
143 |
|
144 | var L5 = lon + sexa.angleFromSec(-0.09033 + 0.03916 * (cLp + sLp) * Math.tan(lat));
|
145 | var B5 = lat + sexa.angleFromSec(0.03916 * (cLp - sLp));
|
146 | return new base.Coord(L5, B5);
|
147 | }
|
148 |
|
149 | export default {
|
150 | Planet: Planet,
|
151 | toFK5: toFK5
|
152 | }; |
\ | No newline at end of file |