-
Notifications
You must be signed in to change notification settings - Fork 73
/
Copy pathequatorial.js
114 lines (90 loc) · 4.1 KB
/
equatorial.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
equatorial.js - by Don Cross - 2021-03-27
Example Node.js program for Astronomy Engine:
https://github.com/cosinekitty/astronomy
Given an observer's location on the Earth, a
date/time, and horizontal coordinates (azimuth, altitude)
for that observer, this program works backwards
to figure out the equatorial coordinates for that
location in the sky. It provides two solutions:
one that includes atmospheric refraction, another
that ignores atmospheric refraction.
To execute, run the command:
node equatorial latitude longitude azimuth altitude [date]
*/
const Astronomy = require('./astronomy.js');
function ParseNumber(text, name) {
const x = Number(text);
if (!Number.isFinite(x)) {
console.error(`ERROR: Not a valid numeric value for ${name}: "${text}"`);
process.exit(1);
}
return x;
}
function ParseDate(text) {
const d = new Date(text);
if (!Number.isFinite(d.getTime())) {
console.error(`ERROR: Not a valid date: "${text}"`);
process.exit(1);
}
return d;
}
function Format(x, length, digits) {
let s = x.toFixed(digits);
while (s.length < length)
s = ' ' + s;
return s;
}
function Solve(refract, observer, time, azimuth, altitude) {
// Convert the angular horizontal coordinates (azimuth, altitude)
// to a horizontal vector (north, west, zenith).
const hor_sphere = new Astronomy.Spherical(altitude, azimuth, 1);
const refraction_option = refract ? 'normal' : null;
const hor_vec = Astronomy.VectorFromHorizon(hor_sphere, time, refraction_option);
// Make a rotation matrix for this observer and date/time that converts
// horizontal coordinates (HOR) to equatorial coordinates in the J2000 epoch (EQJ).
const rot_hor_eqj = Astronomy.Rotation_HOR_EQJ(time, observer);
// Use the rotation matrix to convert the horizontal vector to an equatorial vector.
const eqj_vec = Astronomy.RotateVector(rot_hor_eqj, hor_vec);
// Convert the equatorial vector to equatorial angular coordinates (RA, DEC).
const eqj = Astronomy.EquatorFromVector(eqj_vec);
// Self-check the answers by converting back to horizontal coordinates,
// using a different algorithm that has been tested to work.
// First we need to convert J2000 equatorial (EQJ) to equator-of-date (EQD),
// because the Horizon function expects EQD.
const rot_eqj_eqd = Astronomy.Rotation_EQJ_EQD(time);
const eqd_vec = Astronomy.RotateVector(rot_eqj_eqd, eqj_vec);
const eqd = Astronomy.EquatorFromVector(eqd_vec);
const check_hor = Astronomy.Horizon(time, observer, eqd.ra, eqd.dec, refraction_option);
const alt_error = Math.abs(check_hor.altitude - altitude);
const az_error = Math.abs(check_hor.azimuth - azimuth);
let line = (refract ? ' yes' : ' no ');
line += ' ' + Format(eqj.ra, 10, 4);
line += ' ' + Format(eqj.dec, 10, 4);
line += ' ' + Format(eqd.ra, 10, 4);
line += ' ' + Format(eqd.dec, 10, 4);
line += ' ' + Format(alt_error, 10, 6);
line += ' ' + Format(az_error, 10, 6);
console.log(line);
}
function Demo() {
if (process.argv.length === 6 || process.argv.length === 7) {
const latitude = ParseNumber(process.argv[2]);
const longitude = ParseNumber(process.argv[3]);
const observer = new Astronomy.Observer(latitude, longitude, 0);
const azimuth = ParseNumber(process.argv[4]);
const altitude = ParseNumber(process.argv[5]);
const time = Astronomy.MakeTime((process.argv.length === 7) ? ParseDate(process.argv[6]) : new Date());
// Print a common header for both solutions.
console.log('Refract? J2000_RA J2000_DEC OFDATE_RA OFDATE_DEC ALT_error AZ_error');
// Solve once ignoring atmospheric refraction.
Solve(false, observer, time, azimuth, altitude);
// Solve again considering atmospheric refraction.
Solve(true, observer, time, azimuth, altitude);
process.exit(0);
} else {
console.log('USAGE: node equatorial latitude longitude azimuth altitude [date]');
process.exit(1);
}
}
Demo();