UNPKG

9.85 kBJavaScriptView Raw
1/**
2 * @copyright 2013 Sonia Keys
3 * @copyright 2016 commenthol
4 * @license MIT
5 * @module solar
6 */
7/**
8 * Solar: Chapter 25, Solar Coordinates.
9 *
10 * Partial implementation:
11 *
12 * 1. Higher accuracy positions are not computed with Appendix III but with
13 * full VSOP87 as implemented in package planetposition.
14 *
15 * 2. Higher accuracy correction for aberration (using the formula for
16 * variation Δλ on p. 168) is not implemented. Results for example 25.b
17 * already match the full VSOP87 values on p. 165 even with the low accuracy
18 * correction for aberration, thus there are no more significant digits that
19 * would check a more accurate result. Also the size of the formula presents
20 * significant chance of typographical error.
21 */
22
23import base from './base';
24import coord from './coord';
25import nutation from './nutation';
26
27/**
28 * True returns true geometric longitude and anomaly of the sun referenced to the mean equinox of date.
29 *
30 * @param {Number} T - number of Julian centuries since J2000. See base.J2000Century.
31 * @returns {Object}
32 * {Number} lon = true geometric longitude, ☉, in radians
33 * {Number} ano = true anomaly in radians
34 */
35export function trueLongitude(T) {
36 // (25.2) p. 163
37 var L0 = base.horner(T, 280.46646, 36000.76983, 0.0003032) * Math.PI / 180;
38 var m = meanAnomaly(T);
39 var C = (base.horner(T, 1.914602, -0.004817, -0.000014) * Math.sin(m) + (0.019993 - 0.000101 * T) * Math.sin(2 * m) + 0.000289 * Math.sin(3 * m)) * Math.PI / 180;
40 var lon = base.pmod(L0 + C, 2 * Math.PI);
41 var ano = base.pmod(m + C, 2 * Math.PI);
42 return { lon: lon, ano: ano };
43}
44
45/**
46 * meanAnomaly returns the mean anomaly of Earth at the given T.
47 *
48 * @param {Number} T - number of Julian centuries since J2000. See base.J2000Century.
49 * @returns {Number} Result is in radians and is not normalized to the range 0..2π.
50 */
51export function meanAnomaly(T) {
52 // (25.3) p. 163
53 return base.horner(T, 357.52911, 35999.05029, -0.0001537) * Math.PI / 180;
54}
55
56/**
57 * eccentricity returns eccentricity of the Earth's orbit around the sun.
58 *
59 * @param {Number} T - number of Julian centuries since J2000. See base.J2000Century.
60 * @returns {Number} eccentricity of the Earth's orbit around the sun.
61 */
62export function eccentricity(T) {
63 // (25.4) p. 163
64 return base.horner(T, 0.016708634, -0.000042037, -0.0000001267);
65}
66
67/**
68 * Radius returns the Sun-Earth distance in AU.
69 *
70 * @param {Number} T - number of Julian centuries since J2000. See base.J2000Century.
71 * @returns {Number} Sun-Earth distance in AU
72 */
73export function radius(T) {
74 var _trueLongitude = trueLongitude(T),
75 lon = _trueLongitude.lon,
76 ano = _trueLongitude.ano; // eslint-disable-line
77
78
79 var e = eccentricity(T);
80 // (25.5) p. 164
81 return 1.000001018 * (1 - e * e) / (1 + e * Math.cos(ano));
82}
83
84/**
85 * ApparentLongitude returns apparent longitude of the Sun referenced to the true equinox of date.
86 * Result includes correction for nutation and aberration. Unit is radians.
87 *
88 * @param {Number} T - number of Julian centuries since J2000. See base.J2000Century.
89 * @returns {Number} apparent longitude of the Sun referenced to the true equinox of date.
90 */
91export function apparentLongitude(T) {
92 var Ω = node(T);
93
94 var _trueLongitude2 = trueLongitude(T),
95 lon = _trueLongitude2.lon,
96 ano = _trueLongitude2.ano; // eslint-disable-line
97
98
99 return lon - 0.00569 * Math.PI / 180 - 0.00478 * Math.PI / 180 * Math.sin(Ω);
100}
101
102/**
103 * @private
104 */
105function node(T) {
106 return 125.04 * Math.PI / 180 - 1934.136 * Math.PI / 180 * T;
107}
108
109/**
110 * true2000 returns true geometric longitude and anomaly of the sun referenced to equinox J2000.
111 * Results are accurate to .01 degree for years 1900 to 2100.
112 *
113 * @param {Number} T - number of Julian centuries since J2000. See base.J2000Century.
114 * @returns {Object}
115 * {Number} lon - true geometric longitude, ☉, in radians
116 * {Number} ano - true anomaly in radians
117 */
118export function true2000(T) {
119 var _trueLongitude3 = trueLongitude(T),
120 lon = _trueLongitude3.lon,
121 ano = _trueLongitude3.ano;
122
123 lon -= 0.01397 * Math.PI / 180 * T * 100;
124 return { lon: lon, ano: ano };
125}
126
127/**
128 * trueEquatorial returns the true geometric position of the Sun as equatorial coordinates.
129 *
130 * @param {Number} jde - Julian ephemeris day
131 * @returns {base.Coord}
132 * {Number} ra - right ascension in radians
133 * {Number} dec - declination in radians
134 */
135export function trueEquatorial(jde) {
136 var _trueLongitude4 = trueLongitude(base.J2000Century(jde)),
137 lon = _trueLongitude4.lon,
138 ano = _trueLongitude4.ano; // eslint-disable-line
139
140
141 var ε = nutation.meanObliquity(jde);
142
143 var _base$sincos = base.sincos(lon),
144 ss = _base$sincos[0],
145 cs = _base$sincos[1];
146
147 var _base$sincos2 = base.sincos(ε),
148 sε = _base$sincos2[0],
149 cε = _base$sincos2[1];
150 // (25.6, 25.7) p. 165
151
152
153 var ra = Math.atan2(cε * ss, cs);
154 var dec = sε * ss;
155 return new base.Coord(ra, dec);
156}
157
158/**
159 * apparentEquatorial returns the apparent position of the Sun as equatorial coordinates.
160 *
161 * @param {Number} jde - Julian ephemeris day
162 * @returns {base.Coord}
163 * {Number} ra - right ascension in radians
164 * {Number} dec - declination in radians
165 */
166export function apparentEquatorial(jde) {
167 var T = base.J2000Century(jde);
168 var λ = apparentLongitude(T);
169 var ε = nutation.meanObliquity(jde);
170
171 var _base$sincos3 = base.sincos(λ),
172 sλ = _base$sincos3[0],
173 cλ = _base$sincos3[1];
174 // (25.8) p. 165
175
176
177 var _base$sincos4 = base.sincos(ε + 0.00256 * Math.PI / 180 * Math.cos(node(T))),
178 sε = _base$sincos4[0],
179 cε = _base$sincos4[1];
180
181 var ra = Math.atan2(cε * sλ, cλ);
182 var dec = Math.asin(sε * sλ);
183 return new base.Coord(ra, dec);
184}
185
186/**
187 * trueVSOP87 returns the true geometric position of the sun as ecliptic coordinates.
188 *
189 * Result computed by full VSOP87 theory. Result is at equator and equinox
190 * of date in the FK5 frame. It does not include nutation or aberration.
191 *
192 * @param {planetposition.Planet} planet
193 * @param {Number} jde - Julian ephemeris day
194 * @returns {Object}
195 * {Number} lon - ecliptic longitude in radians
196 * {Number} lat - ecliptic latitude in radians
197 * {Number} range - range in AU
198 */
199export function trueVSOP87(planet, jde) {
200 var _planet$position = planet.position(jde),
201 lon = _planet$position.lon,
202 lat = _planet$position.lat,
203 range = _planet$position.range;
204
205 var s = lon + Math.PI;
206 // FK5 correction.
207 var λp = base.horner(base.J2000Century(jde), s, -1.397 * Math.PI / 180, -0.00031 * Math.PI / 180);
208
209 var _base$sincos5 = base.sincos(λp),
210 sλp = _base$sincos5[0],
211 cλp = _base$sincos5[1];
212
213 var Δβ = 0.03916 / 3600 * Math.PI / 180 * (cλp - sλp);
214 // (25.9) p. 166
215 lon = base.pmod(s - 0.09033 / 3600 * Math.PI / 180, 2 * Math.PI);
216 lat = Δβ - lat;
217 return new base.Coord(lon, lat, range);
218}
219
220/**
221 * apparentVSOP87 returns the apparent position of the sun as ecliptic coordinates.
222 *
223 * Result computed by VSOP87, at equator and equinox of date in the FK5 frame,
224 * and includes effects of nutation and aberration.
225 *
226 * @param {planetposition.Planet} planet
227 * @param {Number} jde - Julian ephemeris day
228 * @returns {base.Coord}
229 * {Number} lon - ecliptic longitude in radians
230 * {Number} lat - ecliptic latitude in radians
231 * {Number} range - range in AU
232 */
233export function apparentVSOP87(planet, jde) {
234 // note: see duplicated code in ApparentEquatorialVSOP87.
235 var _trueVSOP = trueVSOP87(planet, jde),
236 lon = _trueVSOP.lon,
237 lat = _trueVSOP.lat,
238 range = _trueVSOP.range;
239
240 var Δψ = nutation.nutation(jde)[0];
241 var a = aberration(range);
242 lon = lon + Δψ + a;
243 return new base.Coord(lon, lat, range);
244}
245
246/**
247 * apparentEquatorialVSOP87 returns the apparent position of the sun as equatorial coordinates.
248 *
249 * Result computed by VSOP87, at equator and equinox of date in the FK5 frame,
250 * and includes effects of nutation and aberration.
251 *
252 * @param {planetposition.Planet} planet
253 * @param {Number} jde - Julian ephemeris day
254 * @returns
255 * {Number} ra - right ascension in radians
256 * {Number} dec - declination in radians
257 * {Number} range - range in AU
258 */
259export function apparentEquatorialVSOP87(planet, jde) {
260 // note: duplicate code from ApparentVSOP87 so we can keep Δε.
261 // see also duplicate code in time.E().
262 var _trueVSOP2 = trueVSOP87(planet, jde),
263 lon = _trueVSOP2.lon,
264 lat = _trueVSOP2.lat,
265 range = _trueVSOP2.range;
266
267 var _nutation$nutation = nutation.nutation(jde),
268 Δψ = _nutation$nutation[0],
269 Δε = _nutation$nutation[1];
270
271 var a = aberration(range);
272 var λ = lon + Δψ + a;
273 var ε = nutation.meanObliquity(jde) + Δε;
274
275 var _toEquatorial = new coord.Ecliptic(λ, lat).toEquatorial(ε),
276 ra = _toEquatorial.ra,
277 dec = _toEquatorial.dec;
278
279 return new base.Coord(ra, dec, range);
280}
281
282/**
283 * Low precision formula. The high precision formula is not implemented
284 * because the low precision formula already gives position results to the
285 * accuracy given on p. 165. The high precision formula represents lots
286 * of typing with associated chance of typos, and no way to test the result.
287 * @param {Number} range
288 * @returns {Number} aberation
289 */
290export function aberration(range) {
291 // (25.10) p. 167
292 return -20.4898 / 3600 * Math.PI / 180 / range;
293}
294
295export default {
296 trueLongitude: trueLongitude,
297 true: trueLongitude, // BACKWARDS-COMPATIBILITY
298 meanAnomaly: meanAnomaly,
299 eccentricity: eccentricity,
300 radius: radius,
301 apparentLongitude: apparentLongitude,
302 true2000: true2000,
303 trueEquatorial: trueEquatorial,
304 apparentEquatorial: apparentEquatorial,
305 trueVSOP87: trueVSOP87,
306 apparentVSOP87: apparentVSOP87,
307 apparentEquatorialVSOP87: apparentEquatorialVSOP87,
308 aberration: aberration
309};
\No newline at end of file