mirror of
https://github.com/cosinekitty/astronomy.git
synced 2026-05-19 06:17:03 -04:00
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.
This commit is contained in:
@@ -1457,10 +1457,8 @@ Some Astronomy Engine functions allow their `body` parameter to
|
||||
be a user-defined fixed point in the sky, loosely called a "star".
|
||||
This function assigns a right ascension, declination, and distance
|
||||
to one of the eight user-defined stars `Body.Star1`..`Body.Star8`.
|
||||
A star that has not been defined through a call to `DefineStar`
|
||||
defaults to the coordinates RA=0, DEC=0 and a heliocentric distance of 1 light-year.
|
||||
Once defined, the star keeps the given coordinates until
|
||||
a subsequent call to `DefineStar` replaces the coordinates with new values.
|
||||
Stars are not valid until defined. Once defined, they retain their
|
||||
definition until re-defined by another call to `DefineStar`.
|
||||
|
||||
| Type | Parameter | Description |
|
||||
| --- | --- | --- |
|
||||
@@ -1733,7 +1731,7 @@ of the resulting vector.
|
||||
|
||||
| Type | Parameter | Description |
|
||||
| --- | --- | --- |
|
||||
| [`Body`](#Body) | `body` | A body for which to calculate a heliocentric distance: the Sun, Moon, or any of the planets. |
|
||||
| [`Body`](#Body) | `body` | A body for which to calculate a heliocentric distance: the Sun, Moon, any of the planets, or a user-defined star. |
|
||||
| [`Time`](#Time) | `time` | The date and time for which to calculate the heliocentric distance. |
|
||||
|
||||
**Returns**: `float`
|
||||
|
||||
@@ -355,27 +355,23 @@ class Body(enum.Enum):
|
||||
Star8 = 108
|
||||
|
||||
class _StarDef:
|
||||
def __init__(self, ra, dec, dist):
|
||||
self.ra = ra
|
||||
self.dec = dec
|
||||
self.dist = dist
|
||||
def __init__(self):
|
||||
self.ra = 0.0
|
||||
self.dec = 0.0
|
||||
self.dist = 0.0 # signals that the star has not yet been defined
|
||||
|
||||
_StarTable = [
|
||||
_StarDef(0.0, 0.0, AU_PER_LY), # Star1
|
||||
_StarDef(0.0, 0.0, AU_PER_LY), # Star2
|
||||
_StarDef(0.0, 0.0, AU_PER_LY), # Star3
|
||||
_StarDef(0.0, 0.0, AU_PER_LY), # Star4
|
||||
_StarDef(0.0, 0.0, AU_PER_LY), # Star5
|
||||
_StarDef(0.0, 0.0, AU_PER_LY), # Star6
|
||||
_StarDef(0.0, 0.0, AU_PER_LY), # Star7
|
||||
_StarDef(0.0, 0.0, AU_PER_LY), # Star8
|
||||
]
|
||||
_StarTable = [_StarDef() for _ in range(8)]
|
||||
|
||||
def _IsUserDefinedStar(body):
|
||||
return Body.Star1.value <= body.value <= Body.Star8.value
|
||||
def _GetStar(body):
|
||||
if Body.Star1.value <= body.value <= Body.Star8.value:
|
||||
return _StarTable[body.value - Body.Star1.value]
|
||||
return None
|
||||
|
||||
def _GetUserDefinedStar(body):
|
||||
return _StarTable[body.value - Body.Star1.value] if _IsUserDefinedStar(body) else None
|
||||
def _UserDefinedStar(body):
|
||||
star = _GetStar(body)
|
||||
if star and (star.dist > 0.0):
|
||||
return star
|
||||
return None
|
||||
|
||||
def DefineStar(body, ra, dec, distanceLightYears):
|
||||
"""Assign equatorial coordinates to a user-defined star.
|
||||
@@ -385,10 +381,8 @@ def DefineStar(body, ra, dec, distanceLightYears):
|
||||
This function assigns a right ascension, declination, and distance
|
||||
to one of the eight user-defined stars `Body.Star1`..`Body.Star8`.
|
||||
|
||||
A star that has not been defined through a call to `DefineStar`
|
||||
defaults to the coordinates RA=0, DEC=0 and a heliocentric distance of 1 light-year.
|
||||
Once defined, the star keeps the given coordinates until
|
||||
a subsequent call to `DefineStar` replaces the coordinates with new values.
|
||||
Stars are not valid until defined. Once defined, they retain their
|
||||
definition until re-defined by another call to `DefineStar`.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@@ -407,9 +401,9 @@ def DefineStar(body, ra, dec, distanceLightYears):
|
||||
If you don't know the distance to the star, using a large value like 1000 will generally work well.
|
||||
The minimum allowed distance is 1 light-year, which is required to provide certain internal optimizations.
|
||||
"""
|
||||
star = _GetUserDefinedStar(body)
|
||||
star = _GetStar(body)
|
||||
if star is None:
|
||||
raise Error('Body must be a user-defined star, not {}.'.format(body))
|
||||
raise InvalidBodyError(body)
|
||||
if not (0.0 <= ra < 24.0):
|
||||
raise Error('Invalid right ascension: {}'.format(ra))
|
||||
if not (-90.0 <= dec <= +90.0):
|
||||
@@ -4537,8 +4531,8 @@ def HelioVector(body, time):
|
||||
if body == Body.SSB:
|
||||
return _CalcSolarSystemBarycenter(time)
|
||||
|
||||
star = _GetUserDefinedStar(body)
|
||||
if star is not None:
|
||||
star = _UserDefinedStar(body)
|
||||
if star:
|
||||
return VectorFromSphere(Spherical(star.dec, 15.0*star.ra, star.dist), time)
|
||||
|
||||
raise InvalidBodyError(body)
|
||||
@@ -4557,7 +4551,7 @@ def HelioDistance(body, time):
|
||||
----------
|
||||
body : Body
|
||||
A body for which to calculate a heliocentric distance:
|
||||
the Sun, Moon, or any of the planets.
|
||||
the Sun, Moon, any of the planets, or a user-defined star.
|
||||
time : Time
|
||||
The date and time for which to calculate the heliocentric distance.
|
||||
|
||||
@@ -4572,6 +4566,10 @@ def HelioDistance(body, time):
|
||||
if 0 <= body.value < len(_vsop):
|
||||
return _VsopHelioDistance(_vsop[body.value], time)
|
||||
|
||||
star = _UserDefinedStar(body)
|
||||
if star:
|
||||
return star.dist
|
||||
|
||||
return HelioVector(body, time).Length()
|
||||
|
||||
|
||||
@@ -4727,7 +4725,7 @@ def BackdatePosition(time, observerBody, targetBody, aberration):
|
||||
Its `t` field holds the time that light left the observed
|
||||
body to arrive at the observer at the observation time.
|
||||
"""
|
||||
if _IsUserDefinedStar(targetBody):
|
||||
if _UserDefinedStar(targetBody):
|
||||
# This is a user-defined star, which must be treated as a special case.
|
||||
# First, we assume its heliocentric position does not change with time.
|
||||
# Second, we assume its heliocentric position has already been corrected
|
||||
@@ -4958,7 +4956,7 @@ def HelioState(body, time):
|
||||
time
|
||||
)
|
||||
|
||||
if _IsUserDefinedStar(body):
|
||||
if _UserDefinedStar(body):
|
||||
vec = HelioVector(body, time)
|
||||
return StateVector(vec.x, vec.y, vec.z, 0.0, 0.0, 0.0, time)
|
||||
|
||||
@@ -6668,7 +6666,7 @@ def _MaxAltitudeSlope(body, latitude):
|
||||
elif body in [Body.Jupiter, Body.Saturn, Body.Uranus, Body.Neptune, Body.Pluto]:
|
||||
deriv_ra = -0.2
|
||||
deriv_dec = +0.2
|
||||
elif _IsUserDefinedStar(body):
|
||||
elif _UserDefinedStar(body):
|
||||
# The minimum allowed heliocentric distance of a user-defined star
|
||||
# is one light-year. This can cause a tiny amount of parallax (about 0.001 degrees).
|
||||
# Also, including stellar aberration (22 arcsec = 0.006 degrees), we provide a
|
||||
|
||||
Reference in New Issue
Block a user