Skip to content

Commit 098eb3a

Browse files
committed
Optimized HelioDistance for user-defined stars.
Because we instantly know the heliocentric distance of a user-defined star, there is no need to convert it into a vector and then take the length of the vector. All of the HelioDistance functions now return the distance directly, as an optimization. Also, I decided it didn't make sense to have a default definition for user-defined stars. If the caller doesn't define a star, it should be treated as an invalid body.
1 parent 79f6eac commit 098eb3a

27 files changed

+709
-640
lines changed

Diff for: README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ of complexity. So I decided to create Astronomy Engine with the following engine
187187
- Support JavaScript, C, C#, and Python with the same algorithms, and verify them to produce identical results.
188188
(Kotlin support was added in 2022.)
189189
- No external dependencies! The code must not require anything outside the standard library for each language.
190-
- Minified JavaScript code less than 120K. (The current size is <!--MINIFIED_SIZE-->119423 bytes.)
190+
- Minified JavaScript code less than 120K. (The current size is <!--MINIFIED_SIZE-->119438 bytes.)
191191
- Accuracy always within 1 arcminute of results from NOVAS.
192192
- It would be well documented, relatively easy to use, and support a wide variety of common use cases.
193193

Diff for: demo/browser/astronomy.browser.js

+34-24
Original file line numberDiff line numberDiff line change
@@ -290,15 +290,23 @@ const StarList = [
290290
];
291291
;
292292
const StarTable = [
293-
{ ra: 0, dec: 0, dist: exports.AU_PER_LY },
294-
{ ra: 0, dec: 0, dist: exports.AU_PER_LY },
295-
{ ra: 0, dec: 0, dist: exports.AU_PER_LY },
296-
{ ra: 0, dec: 0, dist: exports.AU_PER_LY },
297-
{ ra: 0, dec: 0, dist: exports.AU_PER_LY },
298-
{ ra: 0, dec: 0, dist: exports.AU_PER_LY },
299-
{ ra: 0, dec: 0, dist: exports.AU_PER_LY },
300-
{ ra: 0, dec: 0, dist: exports.AU_PER_LY },
293+
{ ra: 0, dec: 0, dist: 0 },
294+
{ ra: 0, dec: 0, dist: 0 },
295+
{ ra: 0, dec: 0, dist: 0 },
296+
{ ra: 0, dec: 0, dist: 0 },
297+
{ ra: 0, dec: 0, dist: 0 },
298+
{ ra: 0, dec: 0, dist: 0 },
299+
{ ra: 0, dec: 0, dist: 0 },
300+
{ ra: 0, dec: 0, dist: 0 },
301301
];
302+
function GetStar(body) {
303+
const index = StarList.indexOf(body);
304+
return (index >= 0) ? StarTable[index] : null;
305+
}
306+
function UserDefinedStar(body) {
307+
const star = GetStar(body);
308+
return (star && star.dist > 0) ? star : null;
309+
}
302310
/**
303311
* @brief Assign equatorial coordinates to a user-defined star.
304312
*
@@ -307,10 +315,8 @@ const StarTable = [
307315
* This function assigns a right ascension, declination, and distance
308316
* to one of the eight user-defined stars `Star1`..`Star8`.
309317
*
310-
* A star that has not been defined through a call to `DefineStar`
311-
* defaults to the coordinates RA=0, DEC=0 and a heliocentric distance of 1 light-year.
312-
* Once defined, the star keeps the given coordinates until
313-
* a subsequent call to `DefineStar` replaces the coordinates with new values.
318+
* Stars are not valid until defined. Once defined, they retain their
319+
* definition until re-defined by another call to `DefineStar`.
314320
*
315321
* @param {Body} body
316322
* One of the eight user-defined star identifiers:
@@ -332,8 +338,8 @@ const StarTable = [
332338
* The minimum allowed distance is 1 light-year, which is required to provide certain internal optimizations.
333339
*/
334340
function DefineStar(body, ra, dec, distanceLightYears) {
335-
const index = StarList.indexOf(body);
336-
if (index < 0)
341+
const star = GetStar(body);
342+
if (!star)
337343
throw `Invalid star body: ${body}`;
338344
VerifyNumber(ra);
339345
VerifyNumber(dec);
@@ -344,7 +350,9 @@ function DefineStar(body, ra, dec, distanceLightYears) {
344350
throw `Invalid declination for star: ${dec}`;
345351
if (distanceLightYears < 1)
346352
throw `Invalid star distance: ${distanceLightYears}`;
347-
StarTable[index] = { ra: ra, dec: dec, dist: distanceLightYears * exports.AU_PER_LY };
353+
star.ra = ra;
354+
star.dec = dec;
355+
star.dist = distanceLightYears * exports.AU_PER_LY;
348356
}
349357
exports.DefineStar = DefineStar;
350358
var PrecessDirection;
@@ -2483,7 +2491,7 @@ function Horizon(date, observer, ra, dec, refraction) {
24832491
const coszd = Math.cos(zd * exports.DEG2RAD);
24842492
const sinzd0 = Math.sin(zd0 * exports.DEG2RAD);
24852493
const coszd0 = Math.cos(zd0 * exports.DEG2RAD);
2486-
var pr = [];
2494+
const pr = [];
24872495
for (let j = 0; j < 3; ++j) {
24882496
pr.push(((p[j] - coszd0 * uz[j]) / sinzd0) * sinzd + uz[j] * coszd);
24892497
}
@@ -3662,12 +3670,6 @@ exports.JupiterMoons = JupiterMoons;
36623670
*/
36633671
function HelioVector(body, date) {
36643672
var time = MakeTime(date);
3665-
const starIndex = StarList.indexOf(body);
3666-
if (starIndex >= 0) {
3667-
const star = StarTable[starIndex];
3668-
const sphere = new Spherical(star.dec, 15 * star.ra, star.dist);
3669-
return VectorFromSphere(sphere, time);
3670-
}
36713673
if (body in vsop)
36723674
return CalcVsop(vsop[body], time);
36733675
if (body === Body.Pluto) {
@@ -3689,6 +3691,11 @@ function HelioVector(body, date) {
36893691
}
36903692
if (body === Body.SSB)
36913693
return CalcSolarSystemBarycenter(time);
3694+
const star = UserDefinedStar(body);
3695+
if (star) {
3696+
const sphere = new Spherical(star.dec, 15 * star.ra, star.dist);
3697+
return VectorFromSphere(sphere, time);
3698+
}
36923699
throw `HelioVector: Unknown body "${body}"`;
36933700
}
36943701
exports.HelioVector = HelioVector;
@@ -3704,7 +3711,7 @@ exports.HelioVector = HelioVector;
37043711
*
37053712
* @param {Body} body
37063713
* A body for which to calculate a heliocentric distance:
3707-
* the Sun, Moon, or any of the planets.
3714+
* the Sun, Moon, any of the planets, or a user-defined star.
37083715
*
37093716
* @param {FlexibleDateTime} date
37103717
* The date and time for which to calculate the heliocentric distance.
@@ -3713,6 +3720,9 @@ exports.HelioVector = HelioVector;
37133720
* The heliocentric distance in AU.
37143721
*/
37153722
function HelioDistance(body, date) {
3723+
const star = UserDefinedStar(body);
3724+
if (star)
3725+
return star.dist;
37163726
const time = MakeTime(date);
37173727
if (body in vsop)
37183728
return VsopFormula(vsop[body][RAD_INDEX], time.tt / DAYS_PER_MILLENNIUM, false);
@@ -3860,7 +3870,7 @@ class BodyPosition extends PositionFunction {
38603870
function BackdatePosition(date, observerBody, targetBody, aberration) {
38613871
VerifyBoolean(aberration);
38623872
const time = MakeTime(date);
3863-
if (StarList.indexOf(targetBody) >= 0) {
3873+
if (UserDefinedStar(targetBody)) {
38643874
// This is a user-defined star, which must be treated as a special case.
38653875
// First, we assume its heliocentric position does not change with time.
38663876
// Second, we assume its heliocentric position has already been corrected

Diff for: demo/nodejs/astronomy.js

+34-24
Original file line numberDiff line numberDiff line change
@@ -289,15 +289,23 @@ const StarList = [
289289
];
290290
;
291291
const StarTable = [
292-
{ ra: 0, dec: 0, dist: exports.AU_PER_LY },
293-
{ ra: 0, dec: 0, dist: exports.AU_PER_LY },
294-
{ ra: 0, dec: 0, dist: exports.AU_PER_LY },
295-
{ ra: 0, dec: 0, dist: exports.AU_PER_LY },
296-
{ ra: 0, dec: 0, dist: exports.AU_PER_LY },
297-
{ ra: 0, dec: 0, dist: exports.AU_PER_LY },
298-
{ ra: 0, dec: 0, dist: exports.AU_PER_LY },
299-
{ ra: 0, dec: 0, dist: exports.AU_PER_LY },
292+
{ ra: 0, dec: 0, dist: 0 },
293+
{ ra: 0, dec: 0, dist: 0 },
294+
{ ra: 0, dec: 0, dist: 0 },
295+
{ ra: 0, dec: 0, dist: 0 },
296+
{ ra: 0, dec: 0, dist: 0 },
297+
{ ra: 0, dec: 0, dist: 0 },
298+
{ ra: 0, dec: 0, dist: 0 },
299+
{ ra: 0, dec: 0, dist: 0 },
300300
];
301+
function GetStar(body) {
302+
const index = StarList.indexOf(body);
303+
return (index >= 0) ? StarTable[index] : null;
304+
}
305+
function UserDefinedStar(body) {
306+
const star = GetStar(body);
307+
return (star && star.dist > 0) ? star : null;
308+
}
301309
/**
302310
* @brief Assign equatorial coordinates to a user-defined star.
303311
*
@@ -306,10 +314,8 @@ const StarTable = [
306314
* This function assigns a right ascension, declination, and distance
307315
* to one of the eight user-defined stars `Star1`..`Star8`.
308316
*
309-
* A star that has not been defined through a call to `DefineStar`
310-
* defaults to the coordinates RA=0, DEC=0 and a heliocentric distance of 1 light-year.
311-
* Once defined, the star keeps the given coordinates until
312-
* a subsequent call to `DefineStar` replaces the coordinates with new values.
317+
* Stars are not valid until defined. Once defined, they retain their
318+
* definition until re-defined by another call to `DefineStar`.
313319
*
314320
* @param {Body} body
315321
* One of the eight user-defined star identifiers:
@@ -331,8 +337,8 @@ const StarTable = [
331337
* The minimum allowed distance is 1 light-year, which is required to provide certain internal optimizations.
332338
*/
333339
function DefineStar(body, ra, dec, distanceLightYears) {
334-
const index = StarList.indexOf(body);
335-
if (index < 0)
340+
const star = GetStar(body);
341+
if (!star)
336342
throw `Invalid star body: ${body}`;
337343
VerifyNumber(ra);
338344
VerifyNumber(dec);
@@ -343,7 +349,9 @@ function DefineStar(body, ra, dec, distanceLightYears) {
343349
throw `Invalid declination for star: ${dec}`;
344350
if (distanceLightYears < 1)
345351
throw `Invalid star distance: ${distanceLightYears}`;
346-
StarTable[index] = { ra: ra, dec: dec, dist: distanceLightYears * exports.AU_PER_LY };
352+
star.ra = ra;
353+
star.dec = dec;
354+
star.dist = distanceLightYears * exports.AU_PER_LY;
347355
}
348356
exports.DefineStar = DefineStar;
349357
var PrecessDirection;
@@ -2482,7 +2490,7 @@ function Horizon(date, observer, ra, dec, refraction) {
24822490
const coszd = Math.cos(zd * exports.DEG2RAD);
24832491
const sinzd0 = Math.sin(zd0 * exports.DEG2RAD);
24842492
const coszd0 = Math.cos(zd0 * exports.DEG2RAD);
2485-
var pr = [];
2493+
const pr = [];
24862494
for (let j = 0; j < 3; ++j) {
24872495
pr.push(((p[j] - coszd0 * uz[j]) / sinzd0) * sinzd + uz[j] * coszd);
24882496
}
@@ -3661,12 +3669,6 @@ exports.JupiterMoons = JupiterMoons;
36613669
*/
36623670
function HelioVector(body, date) {
36633671
var time = MakeTime(date);
3664-
const starIndex = StarList.indexOf(body);
3665-
if (starIndex >= 0) {
3666-
const star = StarTable[starIndex];
3667-
const sphere = new Spherical(star.dec, 15 * star.ra, star.dist);
3668-
return VectorFromSphere(sphere, time);
3669-
}
36703672
if (body in vsop)
36713673
return CalcVsop(vsop[body], time);
36723674
if (body === Body.Pluto) {
@@ -3688,6 +3690,11 @@ function HelioVector(body, date) {
36883690
}
36893691
if (body === Body.SSB)
36903692
return CalcSolarSystemBarycenter(time);
3693+
const star = UserDefinedStar(body);
3694+
if (star) {
3695+
const sphere = new Spherical(star.dec, 15 * star.ra, star.dist);
3696+
return VectorFromSphere(sphere, time);
3697+
}
36913698
throw `HelioVector: Unknown body "${body}"`;
36923699
}
36933700
exports.HelioVector = HelioVector;
@@ -3703,7 +3710,7 @@ exports.HelioVector = HelioVector;
37033710
*
37043711
* @param {Body} body
37053712
* A body for which to calculate a heliocentric distance:
3706-
* the Sun, Moon, or any of the planets.
3713+
* the Sun, Moon, any of the planets, or a user-defined star.
37073714
*
37083715
* @param {FlexibleDateTime} date
37093716
* The date and time for which to calculate the heliocentric distance.
@@ -3712,6 +3719,9 @@ exports.HelioVector = HelioVector;
37123719
* The heliocentric distance in AU.
37133720
*/
37143721
function HelioDistance(body, date) {
3722+
const star = UserDefinedStar(body);
3723+
if (star)
3724+
return star.dist;
37153725
const time = MakeTime(date);
37163726
if (body in vsop)
37173727
return VsopFormula(vsop[body][RAD_INDEX], time.tt / DAYS_PER_MILLENNIUM, false);
@@ -3859,7 +3869,7 @@ class BodyPosition extends PositionFunction {
38593869
function BackdatePosition(date, observerBody, targetBody, aberration) {
38603870
VerifyBoolean(aberration);
38613871
const time = MakeTime(date);
3862-
if (StarList.indexOf(targetBody) >= 0) {
3872+
if (UserDefinedStar(targetBody)) {
38633873
// This is a user-defined star, which must be treated as a special case.
38643874
// First, we assume its heliocentric position does not change with time.
38653875
// Second, we assume its heliocentric position has already been corrected

0 commit comments

Comments
 (0)