Planetary Position Calculation Guide
Planetary Position Calculation Guide
1. Fundamentals
2. Some useful functions
3. Rectangular and spherical coordinates
4. The time scale. A test date
5. The Sun's position
6. Sidereal time and hour angle. Altitude and azimuth
7. The Moon's position
8. The Moon's position with higher accuracy. Perturbations
9. The Moon's topocentric position
10. The orbital elements of the planets
11. The heliocentric positions of the planets
12. Higher accuracy - perturbations
13. Precession
14. Geocentric positions of the planets
15. The elongation and physical ephemerides of the planets
1. Fundamentals
A celestial body usually orbits the sun in an elliptical orbit. Perturbations from other
planets causes small deviations from this elliptical orbit, but an unperturbed elliptical
orbit can be used as a first approximation, and sometimes as the final approximation.
If the distance from the Sun to the planet always is the same, then the planet follows a
circular orbit. No planet does this, but the orbits of Venus and Neptune are very close
to circles. Among the planets, Mercury and Pluto have orbits that deviate the most
from a circle, i.e. are the most eccentric. Many asteroids have even more eccentric
orbits, but the most eccentric orbits are to be found among the comets. Halley's comet,
for instance, is closer to the Sun than Venus at perihelion, but farther away from the
Sun than Neptune at aphelion. Some comets have even more eccentric orbits that are
best approximated as a parabola. These orbits are not closed - a comet following a
parabolic orbit passes the Sun only once, never to return. In reality these orbits are
extremely elongated ellipses though, and these comets will eventually return,
sometimes after many millennia.
The perihelion and aphelion are the points in the orbit when the planet is closest to
and most distant from the Sun. A parabolic orbit only has a perihelion of course.
The perigee and apogee are points in the Moon's orbit (or the orbit of an artificial
Earth satellite) which are closest to and most distant from the Earth.
The celestial sphere is an imaginary sphere around the observer, at an arbitrary
distance.
The celestial equator is the Earth's equatorial plane projected on the celestial sphere.
The ecliptic is the plane of the Earth's orbit. This is also the plane of the Sun's yearly
apparent motion. The ecliptic is inclined by approximately 23.4_deg to the celestial
equator. The ecliptic intersects the celestial equator at two points: The Vernal Point (or
"the first point of Aries"), and the Autumnal Point. The Vernal Point is the point of
origin for two different commonly used celestial coordinates: equatorial coordinates
and ecliptic coordinates.
Right Ascension and Declination are equatorial coordinates using the celestial
equator as a fundamental plane. At the Vernal Point both the Right Ascension and the
Declination are zero. The Right Ascension is usually measured in hours and minutes,
where one revolution is 24 hours (which means 1 hour equals 15 degrees). It's counted
countersunwise along the celestial equator. The Declination goes from +90 to -90
degrees, and it's positive north of, and negative south of, the celestial equator.
Longitude and Latitude are ecliptic coordinates, which use the ecliptic as a
fundamental plane. Both are measured in degrees, and these coorinates too are both
zero at the Vernal Point. The Longitude is counted countersunwise along the ecliptic.
The Latitude is positive north of the ecliptic. Of course longitude and latitude are also
used as terrestial coordinates, to measure a position of a point on the surface of the
Earth.
Heliocentric, Geocentric, Topocentric. A position relative to the Sun is heliocentric.
If the position is relative to the center of the Earth, then it's geocentric. A topocentric
position is relative to an observer on the surface of the Earth. Within the aim of our
accuracy of 1-2 arc minutes, the difference between geocentric and topocentric
position is negligible for all celestial bodies except the Moon (and some occasional
asteroid which happens to pass very close to the Earth).
The orbital elements consist of 6 quantities which completely define a circular,
elliptic, parabolic or hyperbolic orbit. Three of these quantities describe the shape and
size of the orbit, and the position of the planet in the orbit:
a
e
T
A cirular orbit has zero eccentricity. An elliptical orbit has an eccentricity between
zero and one. A parabolic orbit has an eccentricity of exactly one. Finally, a hyperbolic
orbit has an eccentricity larger than one. A parabolic orbit has an infinite semi-major
axis, a, therefore one instead gives the perihelion distance, q, for a parabolic orbit:
q
Perihelion distance
= a * (1 - e)
It is customary to give q instead of a also for hyperbolic orbit, and for elliptical orbits
with eccentricity close to one.
The three remaining orbital elements define the orientation of the orbit in space:
i
These are the primary orbital elements. From these many secondary orbital elements
can be computed:
q
Perihelion distance
= a * (1 - e)
Aphelion distance
= a * (1 + e)
Orbital period
= 365.256898326 * a**1.5/sqrt(1+m) days,
where m = the mass of the planet in solar masses (0 for
comets and asteroids). sqrt() is the square root function.
Daily motion
Some epoch as a day count, e.g. Julian Day Number. The Time
at Perihelion, T, should then be expressed as the same day count.
t - T
M
= 360_deg / P
degrees/day
Mean Anomaly
= n * (t - T)
(t - T) * 360_deg / P
Mean Longitude
= M + w + N
rem
def
def
def
def
def
def
The function fnrev# normalizes an angle to between 0 and 360 degrees, by adding or
subtracting even mutiples of 360 degrees until the final value falls between 0 and 360.
The # sign means that the function and its argument use double precision. It is
essential that this function uses more than single precision. More about this later.
One warning: some of these functions may divide by zero. If one tries to compute
fnasin(1.0), it's computed as: atn(1/sqrt(1-1.0*1.0)) = atn(1/sqr(0)) = atn(1/0). This is
not such a big problem, since in practice one rarely tries to compute the arc sine of
exactly 1.0. Also, some dialects of Microsoft Basic then just print the warning
message "Overflow", compute 1/0 as the highest possible floating-point number, and
then continue the program. When computing the arctan of this very large number, one
will get pi/2 (or 90 degrees), which is the correct result. However, if you have access
to a more modern, structured, Basic, with the ability to define multi-line function, then
by all means use this to write a better version of arcsin, which treats arcsin(1.0) as a
special case.
There's a similar problem with the fncbrt() function - it only works for positive values.
With a multi-line function definition it can be rewritten to work for negative values
and zero as well, if one follows these simple rules: the Cube Root of zero is of course
zero. The Cube Root of a negative number is computed by making the number
positive, taking the Cube Root of that positive number, and then negating the result.
Two other popular programming language are C and C++. The standard library of
these languages are better equipped with trigonometric functions. You'll find
sin/cos/tan and their inverses, and even an atan2() function among the standard
functions. All you need to do is to define some macros to get the trig functions in
degrees (include all parentheses in these macro definitions), and to define a rev()
function which reduces an angle to between 0 and 360 degrees, and a cbrt() function
which computes the cube root.
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
PI
RADEG
DEGRAD
sind(x)
cosd(x)
tand(x)
asind(x)
acosd(x)
atand(x)
atan2d(y,x)
3.14159265358979323846
(180.0/PI)
(PI/180.0)
sin((x)*DEGRAD)
cos((x)*DEGRAD)
tan((x)*DEGRAD)
(RADEG*asin(x))
(RADEG*acos(x))
(RADEG*atan(x))
(RADEG*atan2((y),(x)))
In C++ the macros could preferably be defined as inline functions instead - this
enables better type checking and also makes overloading of these function names
possible.
The good ol' programming langauge FORTRAN is also well equipped with standard
library trig functions: we find sin/cos/tan + inverses, and also an atan2 but only for
radians. Therefore we need several function definitions to get the trig functions in
degrees too. Below I give code only for SIND, ATAND, ATAN2D, plus REV and
CBRT. The remaining functions COSD, TAND, ASIND and ACOSD are written in a
similar way:
FUNCTION SIND(X)
PARAMETER(RADEG=57.2957795130823)
SIND = SIN( X * (1.0/RADEG) )
END
FUNCTION ATAND(X)
PARAMETER(RADEG=57.2957795130823)
ATAND = RADEG * ATAN(X)
END
FUNCTION ATAN2D(Y,X)
PARAMETER(RADEG=57.2957795130823)
ATAN2D = RADEG * ATAN2(Y,X)
END
FUNCTION REV(X)
REV = X - AINT(X/360.0)*360.0
IF (REV.LT.0.0) REV = REV + 360.0
END
FUNCTION CBRT(X)
IF (X.GE.0.0) THEN
CBRT = X ** (1.0/3.0)
ELSE
CBRT = -((-X)**(1.0/3.0))
ENDIF
END
The programming language Pascal is not as well equipped with trig functions. We
have sin, cos, tan and arctan but nothing more. Therefore we need to write our own
arcsin, arccos and arctan2, plus all the trig functions in degrees, and also the functions
rev and cbrt. The trig functions in degrees are trivial when the others are defined,
therefore I only define arcsin, arccos, arctan2, rev and cbrt:
const pi
= 3.14159265358979323846;
half_pi = 1.57079632679489661923;
function arcsin( x : real ) : real;
begin
if x = 1.0 then
arcsin := half_pi
else if x = -1.0 then
arcsin := -half_pi
else
arcsin := arctan( x / sqrt( 1.0 - x*x ) )
end;
function arccos( x : real ) : real;
begin
arccos := half_pi - arcsin(x);
end;
function arctan2( y, x : real ) : real;
begin
if x = 0.0 then
begin
if y = 0.0 then
It's well worth the effort to ensure that all these functions are available. Then you don't
need to worry about these details which really don't have much to do with the problem
of computing a planetary position.
x = r * cos(RA) * cos(Decl)
y = r * sin(RA) * cos(Decl)
z = r * sin(Decl)
At the north and south celestial poles, both x and y are zero. Since atan2(0,0) is
undefined, the RA is undefined too at the celestial poles. The simplest way to handle
this is to assign RA some arbitrary value, e.g. zero. Close to the celestial poles the
formula asin(z/r) to compute the declination becomes sensitive to round-off errors here the formula atan2(z,sqrt(x*x+y*y)) is preferable.
Not only equatorial coordinates can be converted between spherical and rectangular.
These conversions can also be applied to ecliptic and horizontal coordinates. Just
exchange RA,Decl with long,lat (ecliptic coordinates) or azimuth,altitude (horizontal
coordinates).
A coordinate system can be rotated. If a rectangular coordinate system is rotated
around, say, the X axis, one can easily compute the new x,y,z coordinates. As an
example, let's consider rotating an ecliptic x,y,z system to an equatorial x,y,z system.
This rotation is done around the X axis (which points to the Vernal Point, the common
point of origin in ecliptic and equatorial coordinates), through an angle of oblecl (the
obliquity of the ecliptic, which is approximately 23.4 degrees):
xequat = xeclip
yequat = yeclip * cos(oblecl) - zeclip * sin(oblecl)
zequat = yeclip * sin(oblecl) + zeclip * cos(oblecl)
Now the x,y,z system is equatorial. It's easily rotated back to ecliptic coordinates by
simply switching sign on oblecl:
xeclip = xequat
yeclip = yequat * cos(-oblecl) - zequat * sin(-oblecl)
zeclip = yequat * sin(-oblecl) + zequat * cos(-oblecl)
When computing sin and cos of -oblecl, one can use the identities:
cos(-x) = cos(x), sin(-x) = -sin(x)
Now let's put this together to convert directly from spherical ecliptic coordinates
(long, lat) to spherical equatorial coordinates (RA, Decl). Since the distance r is
Alternatively:
Decl = atan2( 0.3971, sqrt( 0.8423 + 0.0000 ) ) = 23.40_deg
Here we immediately see how simple it is to compute RA, thanks to the atan2()
function: no need to consider in which quadrant it falls, the atan2() function handles
this.
JD - 2451543.5
MJD - 51543.0
We can also compute d directly from the calendar date like this:
d = 367*Y - (7*(Y + ((M+9)/12)))/4 + (275*M)/9 + D - 730530
Y is the year (all 4 digits!), M the month (1-12) and D the date. In this formula all
divisions should be INTEGER divisions. Use "div" instead of "/" in Pascal, and "\"
instead of "/" in Microsoft Basic. In C/C++ and FORTRAN it's sufficient to ensure
that both operands to "/" are integers.
This formula yields d as an integer, which is valid at the start (at midnight), in UT or
TDT, of that calendar date. If you want d for some other time, add UT/24.0 (here the
division is a floating-point division!) to the d obtained above.
Example: compute d for 19 april 1990, at 0:00 UT :
We can look up, or compute the JD for this moment, and we'll get: JD = 2448000.5
which yields d = -3543.0
Or we can compute d directly from the calendar date:
d = 367*1990 - (7*(1990 + ((4+9)/12)))/4 + (275*4)/9 + 19 - 730530
d = 730330 - (7*(1990 + (13/12)))/4 + 1100/9 + 19 - 730530
d = 730330 - (7*(1990 + 1))/4 + 122 + 19 - 730530
d = 730330 - (7*1991)/4 + 122 + 19 - 730530
d = 730330 - 13937/4 + 122 + 19 - 730530
d = 730330 - 3484 + 122 + 19 - 730530
-3543
This moment, 1990 april 19, 0:00 UT/TDT, will be our test date for most numerical
examples below. d is negative since our test date, 19 april 1990, is earlier than the
"point of origin" of our day number, 31 dec 1999.
=
=
=
=
282.9404_deg + 4.70935E-5_deg
* d
1.000000
0.016709 - 1.151E-9
* d
356.0470_deg + 0.9856002585_deg * d
(longitude of perihelion)
(mean distance, a.u.)
(eccentricity)
(mean anomaly)
By definition the Sun is (apparently) moving in the plane of the ecliptic. The
inclination, i, is therefore zero, and the longitude of the ascending node, N, becomes
undefined. For simplicity we'll assign the value zero to N, which means that w, the
angle between acending node and perihelion, becomes equal to the longitude of the
perihelion.
Now let's compute the Sun's position for our test date 19 april 1990. Earlier we've
computed d = -3543.0 which yields:
w
a
e
M
=
=
=
=
282.7735_deg
1.000000
0.016713
-3135.9347_deg
We immediately notice that the mean anomaly, M, will get a large negative value. We
use our function rev() to reduce this value to between 0 and 360 degrees. To do this,
rev() will need to add 9*360 = 3240 degrees to this angle:
M = 104.0653_deg
We also compute:
L = w + M = 386.8388_deg = 26.8388_deg
oblecl = 23.4406_deg
Let's go on computing an auxiliary angle, the eccentric anomaly. Since the eccentricity
of the Sun's (i.e. the Earth's) orbit is so small, 0.017, a first approximation of E will be
accurate enough. Below E and M are in degrees:
E = M + (180/pi) * e * sin(M) * (1 + e * cos(M))
Now we compute the Sun's rectangular coordinates in the plane of the ecliptic, where
the X axis points towards the perihelion:
x = r * cos(v) = cos(E) - e
y = r * sin(v) = sin(E) * sqrt(1 - e*e)
v = arctan2( y, x )
Numerically we get:
r = 1.004323
v = 105.9134_deg
We're done!
How close did we get to the correct values? Let's compare with the Astronomical
Almanac:
lon
r
Our results
Astron. Almanac
28.6869_deg
1.004323
28.6813_deg
1.004311
Difference
+0.0056_deg = 20"
+0.000012
The error in the Sun's longitude was 20 arc seconds, which is well below our aim of
an accuracy of one arc minute. The error in the distance was about 1/3 Earth radius.
Not bad!
Finally we'll compute the Sun's ecliptic rectangular coordinates, rotate these to
equatorial coordinates, and then compute the Sun's RA and Decl:
x = r * cos(lon)
y = r * sin(lon)
z = 0.0
which yields:
xequat = 0.881048
yequat = 0.442312
zequat = 0.191778
= 1h 46m 36.0s
where SIDTIME, GMST0 and UT are given in hours + decimals. GMST0 is the
Sidereal Time at the Greenwich meridian at 00:00 right now, and UT is the same as
Greenwich time. LON is the terrestial longitude in degrees (western longitude is
negative, eastern positive). To "convert" the longitude from degrees to hours we
divide it by 15. If the Sidereal Time becomes negative, we add 24 hours, if it exceeds
24 hours we subtract 24 hours.
Now, how do we compute GMST0? Simple - we add (or subtract) 180 degrees to
(from) L, the Sun's mean longitude, which we've already computed earlier. Then we
normalise the result to between 0 and 360 degrees, by applying the rev() function.
Finally we divide by 15 to convert degrees to hours:
GMST0 = ( L + 180_deg ) / 15 = L/15 + 12h
Now let's compute the local Sidereal Time for the time meridian of Central Europe (at
15 deg east longitude = +15 degrees long) on 19 april 1990 at 00:00 UT:
SIDTIME = GMST0 + UT + LON/15 = 13.78925h + 0 + 15_deg/15 = 14.78925 hours
SIDTIME = 14h 47m 21.3s
To compute the altitude and azimuth we also need to know the Hour Angle, HA. The
Hour Angle is zero when the clestial body is in the meridian i.e. in the south (or, from
the southern heimsphere, in the north) - this is the moment when the celestial body is
at its highest above the horizon.
The Hour Angle increases with time (unless the object is moving faster than the Earth
rotates; this is the case for most artificial satellites). It is computed from:
HA = SIDTIME - RA
Here SIDTIME and RA must be expressed in the same unit, hours or degrees. We
choose hours:
If the Hour Angle is 180_deg the celestial body can be seen (or not be seen, if it's
below the horizon) in the north (or in the south, from the southern hemisphere). We
get HA = 195_deg for the Sun, which seems OK since it's around 01:00 local time.
Now we'll convert the Sun's HA = 195.1808_deg and Decl = +11.0084_deg to a
rectangular (x,y,z) coordinate system where the X axis points to the celestial equator
in the south, the Y axis to the horizon in the west, and the Z axis to the north celestial
pole: The distance, r, is here irrelevant so we set r=1 for simplicity:
x = cos(HA) * cos(Decl) = -0.947346
y = sin(HA) * cos(Decl) = -0.257047
z = sin(Decl)
= +0.190953
Now we'll rotate this x,y,z system along an axis going east-west, i.e. the Y axis, in
such a way that the Z axis will point to the zenith. At the North Pole the angle of
rotation will be zero since there the north celestial pole already is in the zenith. At
other latitudes the angle of rotation becomes 90_deg - latitude. This yields:
xhor = x * cos(90_deg - lat) - z * sin(90_deg - lat)
yhor = y
zhor = x * sin(90_deg - lat) + z * cos(90_deg - lat)
Why did we add 180_deg to the azimuth? To adapt to the most common way to
specify azimuth: from North (0_deg) through East (90_deg), South (180_deg), West
(270_deg) and back to North. If we didn't add 180_deg the azimuth would be counted
from South through West/etc instead. If you want to use that kind of azimuth, then
don't add 180_deg above.
We select some place in central Scandinavia: the longitude is as before +15_deg
(15_deg East), and the latitude is +60_deg (60_deg N):
xhor = -0.947346 * sin(60_deg) - (+0.190953) * cos(60_deg) = -0.915902
yhor = -0.257047
= -0.257047
zhor = -0.947346 * cos(60_deg) + (+0.190953) * sin(60_deg) = -0.308303
Now we've computed the horizontal coordinates in rectangular form. To get azimuth
and altitude we convert to spherical coordinates (r=1):
azimuth
15.6767_deg
The Sun is thus 17.96_deg below the horizon at this moment and place. This is very
close to astronomical twilight (18_deg below the horizon).
=
=
=
=
=
=
125.1228_deg - 0.0529538083_deg * d
5.1454_deg
318.0634_deg + 0.1643573223_deg * d
60.2666
0.054900
115.3654_deg + 13.0649929509_deg * d
= 312.7381_deg
=
5.1454_deg
= -264.2546_deg
=
60.2666
=
0.054900
= -46173.9046_deg
Now the need for sufficient numerical accuracy becomes obvious. If we would
compute M with normal single precision, i.e. only 7 decimal digits of accuracy, then
the error in M would here be about 0.01 degrees. Had we selected a date around 1901
or 2099 then the error in M would have been about 0.1 degrees, which is definitely
worse than our aim of a maximum error of one or two arc minutes. Therefore, when
computing the Moon's mean anomaly, M, it's important to use at least 9 or 10 digits of
accuracy.
(This was a real problem around 1980, when microcomputers were a novelty. Around
then, pocket calculators usually offered better precision than microcomputers. But
these days are long gone: nowadays microcomputers routinely offer double precision
(14-16 digits of accuracy) support in hardware; all you need to do is to select a
compiler which really suports this.)
All angular elements should be normalized to within 0-360 degrees, by calling the
rev() function. We get:
N
i
w
a
e
M
= 312.7381_deg
=
5.1454_deg
= 95.7454_deg
= 60.2666
=
0.054900
= 266.0954_deg
The eccentricity of the Moon's orbit is larger than of the Earth's orbit. This means that
our first approximation will have a bigger error - it'll be close to the limit of what we
can tolerate within our accuracy aim. If you want to be careful, you should therefore
use the iteration formula below: set E0 to our first approximation, compute E1, then
set E0 to E1 and compute a new E1, until the difference between E0 and E1 becomes
small enough, i.e. smaller than about 0.005 degrees. Then use the last E1 as the final
value. In the formula below, E0, E1 and M are in degrees:
E1 = E0 - (E0 - (180_deg/pi) * e * sin(E0) - M) / (1 - e * cos(E0))
Now we know the Moon's position in the plane of the lunar orbit. To compute the
Moon's position in ecliptic coordinates, we apply these formulae:
xeclip = r * ( cos(N) * cos(v+w) - sin(N) * sin(v+w) * cos(i) )
yeclip = r * ( sin(N) * cos(v+w) + cos(N) * sin(v+w) * cos(i) )
zeclip = r * sin(v+w) * sin(i)
mean longitude:
mean longitude:
mean anomaly:
mean anomaly:
mean elongation:
argument of latitude:
Ls
Lm
Ms
Mm
D
F
=
=
=
(already computed)
N + w + M (for the Moon)
(already computed)
(already computed)
Lm - Ls
Lm - N
= 104.0653_deg
= 266.0954_deg
= 26.8388_deg
= 312.7381_deg + 95.7454_deg + 266.0954_deg = 674.5789_deg
D
F
= 314.5789_deg
= 314.5789_deg - 26.8388_deg = 287.7401_deg
= 314.5789_deg - 312.7381_deg = 1.8408_deg
Now it's time to compute and add up the 12 largest perturbation terms in longitude,
the 5 largest in latitude, and the 2 largest in distance. These are all the perturbation
terms with an amplitude larger than 0.01_deg in longitude resp latitude. In the lunar
distance, only the perturbation terms larger than 0.1 Earth radii has been included:
Perturbations in longitude (degrees):
-1.274_deg
+0.658_deg
-0.186_deg
-0.059_deg
-0.057_deg
+0.053_deg
+0.046_deg
+0.041_deg
-0.035_deg
-0.031_deg
-0.015_deg
+0.011_deg
*
*
*
*
*
*
*
*
*
*
*
*
sin(Mm - 2*D)
(Evection)
sin(2*D)
(Variation)
sin(Ms)
(Yearly equation)
sin(2*Mm - 2*D)
sin(Mm - 2*D + Ms)
sin(Mm + 2*D)
sin(2*D - Ms)
sin(Mm - Ms)
sin(D)
(Parallactic equation)
sin(Mm + Ms)
sin(2*F - 2*D)
sin(Mm - 4*D)
*
*
*
*
*
sin(F - 2*D)
sin(Mm - F - 2*D)
sin(Mm + F - 2*D)
sin(F + 2*D)
sin(2*Mm + F)
Some of the largest perturbation terms in longitude even have received individual
names! The largest perturbation, the Evection, was discovered already by Ptolemy (he
made it one of the epicycles in his theory for the Moon's motion). The two next largest
perturbations, the Variation and the Yearly equation, were discovered by Tycho Brahe.
If you don't need 1-2 arcmin accuracy, you don't need to compute all these
perturbation terms. If you only include the two largest terms in longitude and the
largest in latitude, the error in longitude rarely becomes larger than 0.25_deg, and in
latitude rarely larger than 0.15_deg.
Let's compute these perturbation terms for our test date:
longitude: -0.9847 - 0.3819 - 0.1804 + 0.0405 - 0.0244 + 0.0452 +
0.0428 + 0.0126 - 0.0333 - 0.0055 - 0.0079 - 0.0029
= -1.4132_deg
=
=
=
306.9484_deg
-0.5856_deg
60.6779 Earth radii
latitude -0.55_deg,
where r is the Moon's distance in Earth radii. It's simplest to apply the correction in
horizontal coordinates (azimuth and altitude): within our accuracy aim of 1-2 arc
minutes, no correction need to be applied to the azimuth. One need only apply a
correction to the altitude above the horizon:
alt_topoc = alt_geoc - mpar * cos(alt_geoc)
rho = 1.0
However, if we do wish to account for the flattening of the Earth, we instead compute:
gclat = lat - 0.1924_deg * sin(2*lat)
rho
= 0.99833 + 0.00167 * cos(2*lat)
Now we're ready to convert the geocentric Right Ascention and Declination (RA,
Decl) to their topocentric values (topRA, topDecl):
topRA
= RA - mpar * rho * cos(gclat) * sin(HA) / cos(Decl)
topDecl = Decl - mpar * rho * sin(gclat) * sin(g - Decl) / sin(g)
Let's do this correction for our test date and for the geographical position 15 deg E
longitude (= +15_deg) and 60 deg N latitude (= +60_deg). Earlier we computed the
Local Sidereal Time as LST = SIDTIME = 14.78925 hours. Multiply by 15 to get
degrees: LST = 221.8388_deg
The Moon's Hour Angle becomes:
HA = LST - RA = -87.6623_deg = 272.3377_deg
Our latitude +60_deg yields the following geocentric latitude and distance from the
Earth's center:
gclat = 59.83_deg
rho
= 0.9975
We've already computed the Moon's distance as 60.6779 Earth radii, which means the
Moon's parallax is:
mpar = 0.9443_deg
g = 88.642
This correction to topocentric position can also be applied to the Sun and the planets.
But since they're much farther away, the correction becomes much smaller. It's largest
for Venus at inferior conjunction, when Venus' parallax is somewhat larger than 32 arc
seconds. Within our aim of obtaining a final accuracy of 1-2 arc minutes, it might
barely be justified to correct to topocentric position when Venus is close to inferior
conjunction, and perhaps also when Mars is at a favourable opposition. But in all
other cases this correction can safely be ignored within our accuracy aim. We only
need to worry about the Moon in this case.
If you want to compute topocentric coordinates for the planets anyway, you do it the
same way as for the Moon, with one exception: the parallax of the planet (ppar) is
computed from this formula:
ppar = (8.794/3600)_deg / r
where r is the distance of the planet from the Earth, in astronomical units.
= 48.3313_deg
=
7.0047_deg
= 29.1241_deg
= 0.387098
= 0.205635
= 168.6562_deg
+ 3.24587E-5_deg
+ 5.00E-8_deg
+ 1.01444E-5_deg
* d
* d
* d
+ 5.59E-10
* d
+ 4.0923344368_deg * d
Venus:
N
i
w
a
e
M
= 76.6799_deg
=
3.3946_deg
= 54.8910_deg
= 0.723330
= 0.006773
= 48.0052_deg
+ 2.46590E-5_deg
+ 2.75E-8_deg
+ 1.38374E-5_deg
* d
* d
* d
- 1.302E-9
* d
+ 1.6021302244_deg * d
Mars:
N =
49.5574_deg + 2.11081E-5_deg
* d
i
w
a
e
M
=
1.8497_deg - 1.78E-8_deg
= 286.5016_deg + 2.92961E-5_deg
= 1.523688
= 0.093405
+ 2.516E-9
= 18.6021_deg + 0.5240207766_deg
* d
* d
* d
* d
Jupiter:
N
i
w
a
e
M
=
=
=
=
=
=
100.4542_deg
1.3030_deg
273.8777_deg
5.20256
0.048498
19.8950_deg
+ 2.76854E-5_deg
- 1.557E-7_deg
+ 1.64505E-5_deg
113.6634_deg
2.4886_deg
339.3939_deg
9.55475
0.055546
316.9670_deg
+ 2.38980E-5_deg
- 1.081E-7_deg
+ 2.97661E-5_deg
* d
* d
* d
+ 4.469E-9
* d
+ 0.0830853001_deg * d
Saturn:
N
i
w
a
e
M
=
=
=
=
=
=
* d
* d
* d
- 9.499E-9
* d
+ 0.0334442282_deg * d
Uranus:
N
i
w
a
e
M
= 74.0005_deg
=
0.7733_deg
= 96.6612_deg
= 19.18171
= 0.047318
= 142.5905_deg
+
+
+
+
+
1.3978E-5_deg
1.9E-8_deg
3.0565E-5_deg
1.55E-8
7.45E-9
0.011725806_deg
*
*
*
*
*
*
d
d
d
d
d
d
+
+
+
+
3.0173E-5_deg
2.55E-7_deg
6.027E-6_deg
3.313E-8
2.15E-9
0.005995147_deg
*
*
*
*
*
*
d
d
d
d
d
d
Neptune:
N
i
w
a
e
M
=
=
=
=
=
=
131.7806_deg
1.7700_deg
272.8461_deg
30.05826
0.008606
260.2471_deg
Let's compute all these elements for our test date, 19 april 1990 0h UT:
N
deg
i
deg
w
deg
Mercury
Venus
Mars
48.2163
76.5925
49.4826
7.0045
3.3945
1.8498
29.0882
54.8420
286.3978
Jupiter
Saturn
Uranus
Neptune
100.3561
113.5787
73.9510
131.6737
1.3036
2.4890
0.7732
1.7709
273.8194
339.2884
96.5529
272.8675
a
a.e.
0.387098
0.723330
1.523688
5.20256
9.55475
19.18176
30.05814
M
deg
0.205633
0.006778
0.093396
69.5153
131.6578
321.9965
0.048482
0.055580
0.047292
0.008598
85.5238
198.4741
101.0460
239.0063
The heliocentric ecliptic coordinates of the planets are computed in the same way as
we computed the geocentric ecliptic coordinates of the Moon: first we compute E, the
eccentric anomaly. Several planetary orbits have quite high eccentricities, which
means we must use the iteration formula to obtain an accurate value of E. When we
know E, we compute, as earlier, the distance r ("radius vector") and the true anomaly,
v. Then we compute ecliptic rectangular (x,y,z) coordinates as we did for the Moon.
Since the Moon orbits the Earth, this position of the Moon was geocentric. The
planets though orbit the Sun, which means we get heliocentric positions instead. Also
the semi-major axis, a, and the distance, r, which was given in Earth radii for the
Moon, are given in astronomical units for the planets, where one astronomical unit is
149.6 million kilometers.
Let's do this for Mercury on our test date: the first approximation of E is 81.3464_deg,
and following iterations yield 81.1572_deg, 81.1572_deg .... From this we find:
r = 0.374862
v = 93.0727_deg
The agreement is almost perfect! The discrepancy is only a few arc seconds. This is
because it's quite easy to get an accurate position for Mercury: it's close to the Sun
where the Sun's gravitational field is strongest, and therefore perturbations from the
other planets will be smallest for Mercury.
If we compute the heliocentric longitude, latitude and distance for the other planets
from their orbital elements, we get:
Mercury
Venus
Mars
Heliocentric
longitude
latitude
lon
lat
distance
r
170.5709_deg
263.6570_deg
290.6297_deg
0.374862
0.726607
1.417194
+5.9255_deg
-0.4180_deg
-1.6203_deg
Jupiter
Saturn
Uranus
Neptune
105.2543_deg
289.4523_deg
276.7999_deg
282.7192_deg
+0.1113_deg
+0.1792_deg
-0.3003_deg
+0.8575_deg
5.19508
10.06118
19.39628
30.19284
The difference is here much larger! For Mercury our discrepancy was only a few arc
seconds, but for Saturn it's up to four arc minutes! And still we've been lucky, since
sometimes the discrepancy can be up to one full degree for Saturn. This is the planet
that's perturbed most severely, mostly by Jupiter.
Mj
Ms
Mu
*
*
*
*
*
*
*
sin(2*Mj
sin(2*Mj
sin(3*Mj
sin(Mj cos(Mj sin(2*Mj
sin(Mj -
- 5*Ms
- 2*Ms
- 5*Ms
2*Ms)
Ms)
- 3*Ms
5*Ms -
- 67.6_deg)
+ 21_deg)
+ 21_deg)
+ 52_deg)
69_deg)
For Saturn we must correct both the longitude and latitude. Add this to Saturn's
heliocentric longitude:
+0.812_deg
-0.229_deg
+0.119_deg
+0.046_deg
+0.014_deg
*
*
*
*
*
sin(2*Mj
cos(2*Mj
sin(Mj sin(2*Mj
sin(Mj -
- 5*Ms
- 4*Ms
2*Ms - 6*Ms
3*Ms +
- 67.6_deg)
- 2_deg)
3_deg)
- 69_deg)
32_deg)
The perturbation terms above are all terms having an amplitude of 0.01 degrees or
more. We ignore all perturbations in the distances of the planets, since a modest
perturbation in distance won't affect the apparent position very much.
The largest perturbation term, "the grand Jupiter-Saturn term" is the perturbation in
longitude with the largest amplitude in both Jupiter and Saturn. Its period is 918 years,
and its amplitude is a large part of a degree for both Jupiter and Saturn. There is also a
"grand Saturn-Uranus term", which has a period of 560 years and an amplitude of
0.035 degrees for Uranus, but less than 0.01 degrees for Saturn. Other included terms
have periods between 14 and 100 years. Finally we should mention the "grand
Uranus-Neptune term", which has a period if 4200 years and an amplitude of almost
one degree. It's not included in our perturbation terms here, instead its effects have
been included in the orbital elements for Uranus and Neptune. This is why the mean
distances of Uranus and Neptune are varying.
If we compute the perturbations for our test date, we get:
Mj = 85.5238_deg
Ms = 198.4741_deg
Mu = 101.0460:
105.2423_deg
105.2603_deg
289.3824_deg
289.3864_deg
+0.1845_deg
+0.1816_deg
276.7672_deg
276.7706_deg
13. Precession
The planetary positions computed here are for "the epoch of the day", i.e. relative to
the celestial equator and ecliptic at the moment. Sometimes you need to use some
other epoch, e.g. some standard epoch like 1950.0 or 2000.0. Due to our modest
accuracy requirement of 1-2 arc minutes, we need not distinguish J2000.0 from
B2000.0, it's enough to simply use 2000.0.
We will simplify the precession correction further by doing it in eliptic coordinates:
the correction is simply done by adding
3.82394E-5_deg * ( 365.2422 * ( epoch - 2000.0 ) - d )
So we simply add 0.1355_deg to our ecliptic longitude to get the position at 2000.0.
But for the moment we want the "epoch of the day": let's rotate the x,y,z, coordinates
around the X axis, as described earlier. Then we'll get equatorial rectangular
geocentric (whew!) coordinates:
xequat = +0.513227
yequat = +0.482961
zequat = 0.251582
We can convert these coordinates to spherical coordinates, and then we'll (finally!) get
geocentric Right Ascension, Declination and distance for Mercury:
RA = 43.2598_deg
Decl = +19.6460_deg
R = 0.748296
Note that the distance now is different. This is quite natural since the distance now is
from the Earth and not, as earlier, from the Sun.
Let's conclude by checking the values given by the Astronomical Almanac:
RA = 43.2535_deg
Decl = +19.6458_deg
R = 0.748262
6.74"
16.92"
17.59"
9.36"
196.94"
165.6"
65.8"
62.2"
equ
equ
equ
equ
equ
equ
17.53"
9.28"
185.08"
150.8"
62.1"
60.9"
pol
pol
pol
pol
pol
pol
The Sun's apparent diameter at 1 astronomical unit is 1919.26". The Moon's apparent
diameter is:
d = 1873.7" * 60 / r
When we know the phase angle, we can easily compute the phase:
phase
( 1 + cos(FV) ) / 2
hav(180_deg - FV)
hav is the "haversine" function. The "haversine" (or "half versine") is an old and now
obsolete trigonometric function. It's defined as:
hav(x)
( 1 - cos(x) ) / 2
sin^2 (x/2)
As usual we must use a different procedure for the Moon. Since the Moon is so close
to the Earth, the procedure above would introduce too big errors. Instead we use the
Moon's ecliptic longitude and latitude, mlon and mlat, and the Sun's ecliptic longitude,
mlon, to compute first the elongation, then the phase angle, of the Moon:
elong = acos( cos(slon - mlon) * cos(mlat) )
FV = 180_deg - elong
Finally we'll compute the magnitude (or brightness) of the planets. Here we need to
use a formula that's different for each planet. The phase angle, FV, is in degrees:
Mercury:
Venus:
Mars:
Jupiter:
Saturn:
Uranus:
Neptune:
-0.36
-4.34
-1.51
-9.25
-9.0
-7.15
-6.90
+
+
+
+
+
+
+
5*log10(r*R)
5*log10(r*R)
5*log10(r*R)
5*log10(r*R)
5*log10(r*R)
5*log10(r*R)
5*log10(r*R)
+
+
+
+
+
+
+
0.027
0.013
0.016
0.014
0.044
0.001
0.001
*
*
*
*
*
*
*
FV + 2.2E-13 * FV**6
FV + 4.2E-7 * FV**3
FV
FV
FV + ring_magn
FV
FV
** is the power operator, thus FV**6 is the phase angle (in degrees) raised to the sixth
power. If FV is 150 degrees, then FV**6 becomes ca 1.14E+13, which is a quite large
number.
Saturn needs special treatment due to its rings: when Saturn's rings are "open" then
Saturn will appear much brighter than when we view Saturn's rings edgewise. We'll
compute ring_mang like this:
ring_magn = -2.6 * sin(abs(B)) + 1.2 * (sin(B))**2
Here B is the tilt of Saturn's rings which we also need to compute. Then we start with
Saturn's geocentric ecliptic longitude and latitude (los, las) which we've already
computed. We also need the tilt of the rings to the ecliptic, ir, and the "ascending
node" of the plane of the rings, Nr:
ir = 28.06_deg
Nr = 169.51_deg + 3.82E-5_deg * d
Here d is our "day number" which we've used so many times before. For our test date
d = -3543. Now let's compute the tilt of the rings:
B = asin( sin(las) * cos(ir) - cos(las) * sin(ir) * sin(los-Nr) )
than one year old, the errors usually stay below approximately one arc minute, for a
main-belt asteroid.
If you have access to valid orbital elements for a comet or an asteroid, proceed as
below to compute its position at some date:
1. If necessary, precess the angular elements N,w,i to the epoch of today. The simples
way to do this is to add the precession angle to N, the longitude of the ascending node.
This method is approximate, but it's good enough for our accuracy aim of 1-2 arc
minutes.
2. Compute the day number for the time or perihelion, call it D. Then compute the
number of days since perihelion, d - D (before perihelion this number is of course
negative).
3. If the orbit is elliptical, compute the Mean Anomaly, M. Then compute r, the
heliocentric distance, and v, the true anomaly.
4. If the orbit is a parabola, or close to a parabola (the eccentricity is 1.0 or nearly
1.0), then the algorithms for elliptical orbits will break down. Then use another
algorithm, presented below, to compute r, the heliocentric distance, and v, the true
anomaly, for near-parabolic orbits.
5. When you know r and v, proceed as with the planets: compute first the heliocentric,
then the geocentric, position.
6. If needed, precess the final position to the desired epoch, e.g. 2000.0
A quantity we'll encounter here is Gauss' gravitational constant, k. This constant links
the Sun's mass with our time unit (the day) and the length unit (the astronomical unit).
The EXACT value of Gauss' gravitational constant k is:
k = 0.01720209895
(exactly!)
If the orbit is elliptical, and if the perihelion distance, q, is given instead of the mean
distance, a, we start by computing the mean distance a from the perihelion distance q
and the eccentricity e:
a = q / (1 - e)
sqrt(a*a*a)
If the comet's orbit is a parabola, the algorithm for elliptic orbits will break down: the
semi-major axis and the orbital period will be infinite, and the Mean Anomaly will be
zero. Then we must proceed in a different way. For a parabolic orbit we start by
computing the quantities a, b and w (where a is not at all related to a for an elliptic
orbit):
a = 1.5 * (d - D) * k / sqrt(2 * q*q*q)
b = sqrt( 1 + a*a )
w = cbrt(b + a) - cbrt(b - a)
cbrt is the Cubic Root function. Finally we compute the true anomaly, v, and the
heliocentric distiance, r:
v = 2 * atan(w)
r = q * ( 1 + w*w )
=
=
=
=
w = W * ( 1 + f * C * ( a1 + a2*g + a3*g*g ) )
v = 2 * atan(w)
r = q * ( 1 + w*w ) / ( 1 + w*w * f )
This algorithm yields the true anomaly, v, and the heliocentric distance, r, for a nearlyparabolic orbit.
Now it's time for a practical example. Let's select two of the comets that were seen in
the autumn of 1990: Comet Encke, a well-known periodic comet, and comet Levy,
which was easily seen towards a dark sky in the autumn of 1990. When passing the
inner solar system, the orbit of comet Levy was slightly hyperbolic.
According the the Handbook of the British Astronomical Association the orbital
elements for comet Encke in 1990 are:
T
e
q
w
N
i
=
=
=
=
=
=
The orbital elements for comet Levy are (BAA Circular 704):
T
e
q
w
N
i
=
=
=
=
=
=
Let's also choose another test date, when both these comets were visible: 1990 Aug
22, 0t UT, which yields a "day number" d = -3418.0
Now we compute the day numbers at perihelion for these two comets. We get for
comet Encke:
D = -3350.45498
d - D = -67.54502
d - D = -63.6954
The first approximation plus successive approximation for the Eccentric anomaly, E,
becomes (degrees):
E = 309.3811
293.5105
295.8474
295.9061
295.9061_deg ....
Here we clearly see the great need for iteration: the initial approximation differs from
the final value by 14 degrees. Finally we compute the true anomaly, v, and
heliocentric distance, r, for comet Encke:
v = 228.8837_deg
r = 1.3885
Now it's time for comet Levy: we'll compute the true anomaly, v, and the heliocentric
distance, r, for Levy in two different ways. First we'll pretend that the orbit of Levy is
an exact parabola. We get:
a = -1.2780823
b = 1.6228045
w = -0.7250189
v = -71.8856_deg
r = 1.431947
Then we repeat the computation but accounts for the fact that Levy's orbit deviates
slightly from a parabola. We get:
a =
c =
a1=
w =
-1.2781686
2.9022000
0.8769495
-0.7250270
b = 1.6228724
f = -1.3498E-4
a2= 1.9540987
W = -0.7250566
g = -1.60258E-5
a3= 1.5403455
v = -71.8863_deg
r = 1.432059
The difference is small in this case - only 0.0007 degrees or 2.5 arc seconds in true
anomaly, and 0.000112 a.u. in heliocentric distance. Here it would have been
sufficient to treat Levy's orbit as an exact parabola.
Now we know the true anomaly, v, and the heliocentric distance, r, for both Encke and
Levy. Next we proceed by precessing N, the longitude of the ascending node, from
1950.0 to the "epoch of the day". Let's compute the precession angle from 1950.0 to
1990 Aug 22:
prec = 3.82394E-5_deg * ( 365.2422 * ( 1950.0 - 2000.0 ) - (-3418) )
prec = -0.5676_deg
To precess from 1990 Aug 22 to 1950.0, we should add this angle to N. But now we
want to do the opposite: precess from 1950.0 to 1990 Aug 22, therefore we must
instead subtract this angle:
For comet Encke we get:
N = 334.04096_deg - (-0.5676_deg) = 334.60856_deg
Using this modified value for N we proceed just like for the planets. I won't repeat the
details, but merely state some intermediate and final results:
Sun's position:
Heliocentric:
x = -0.863890
Encke
Levy
+1.195087
+0.666455
+0.235663
+1.169908
-0.807922
+0.171375
x
y
z
Geoc., eclipt.:
x
y
z
Geoc., equat.:
x
y
z
RA
Decl
R
y = +0.526123
Encke
Levy
+0.331197
+1.192579
+0.235663
+0.306018
-0.281799
+0.171375
Encke
Levy
+0.331197
+1.000414
+0.690619
+0.306018
-0.326716
+0.045133
71.6824_deg
+33.2390_deg
1.259950
313.1264_deg
+5.7572_deg
0.449919
These positions are for the "epoch of the day". If you want positions for some
standard epoch, e.g. 2000.0, these positions must be precessed to that epoch.
Finally some notes about computing the magnitude of a comet. To accurately predict a
comet's magnitude is usually hard and sometimes impossible. It's fairly common that a
magnitude prediction is off by 1-2 magnitudes or even more. For comet Levy the
magnitude formula looked like this:
m = 4.0 * 5*log10(R) + 10*log10(r)
where R is the geocentric distance and r the heliocentric distance. The general case is:
m = G * 5*log10(R) + H*log10(r)
where H usually is around 10. If H is unknown, it's usually assumed to be 10. Each
comet has it's own G and H.
Some comets have a different magnitude formula. One good example is comet Encke,
where the magnitude formula looks like this:
m1 = 10.8 + 5*log10(R) + 3.55 * ( r**1.8 - 1 )
"m1" refers to the total magnitude of the comet. There is another cometary magnitude,
"m2", which refers to the magnitude of the nucleus of the comet. The magnitude
formula for Encke's m2 magnitude looks like this:
m2 = 14.5 + 5*log10(R) + 5*log10(r) + 0.03*FV
Here FV is the phase angle. This kind of magnitude formula looks very much like the
magnitude formula of asteroids, for a very good reason: when a comet is far away
form the Sun, no gases are evaporated from the surface of the comet. Then the comet
has no tail (of course) and no coma, only a nucleus. Which means the comet then
behaves much like an asteroid.
During the last few years it's become increasingly obvious that comets and asteroids
often are similar kinds of solar-system objects. The asteroid (2060) Chiron has
displayed cometary activity and is now also considered a comet. And in some cases
comets that have "disappeared" have been re-discovered as asteroids! Apparently they
"ran out of gas" and what remains of the former comet is only rock, i.e. an asteroid.