v07i011: astronomical ephemeris - 3 of 3
Brandon S. Allbery - comp.sources.misc
allbery at uunet.UU.NET
Sun Jun 4 11:43:31 AEST 1989
Posting-number: Volume 7, Issue 11
Submitted-by: ecd at ncs-med.UUCP (Elwood C. Downey)
Archive-name: ephem/part03
[BTW, not putting "guard characters" at the beginnings of lines in a shar'ed
file is asking for trouble on some systems. Especially with idiot UUCP mail
systems -- some, perhaps all, of this group *does* get sent over mail links.
One "From" will produce a mangled transmission. And Bitnet seems to know of
other ways to destroy such files. ++bsa]
#!/bin/sh
echo mkdir lib
mkdir lib
echo cd lib
cd lib
echo extracting Makefile
cat > Makefile << 'xXx'
CLNFLAGS=$(CLNF)
LNFLAGS=$(CLNFLAGS) $(LNF)
CFLAGS=$(CLNFLAGS) $(CF)
LINTFLAGS=$(CFLAGS) $(LINTF)
LINTLIBS=
.c.a:
-$(CC) -c $(CFLAGS) $<
.PRECIOUS: lib.a
lib.a: lib.a(aa_hadec.o) \
lib.a(anomaly.o) \
lib.a(cal_mjd.o) \
lib.a(eq_ecl.o) \
lib.a(moon.o) \
lib.a(moonnf.o) \
lib.a(moonrs.o) \
lib.a(nutation.o) \
lib.a(obliq.o) \
lib.a(parallax.o) \
lib.a(pelement.o) \
lib.a(plans.o) \
lib.a(precess.o) \
lib.a(refract.o) \
lib.a(riset.o) \
lib.a(sex_dec.o) \
lib.a(sun.o) \
lib.a(sunrs.o) \
lib.a(utc_gst.o)
ar rv $@ $?
ranlib $@
rm -f $?
xXx
echo extracting aa_hadec.c
cat > aa_hadec.c << 'xXx'
#include <stdio.h>
#include <math.h>
#include "astro.h"
/* given latitude (n+, radians), lat, altitude (up+, radians), alt, and
* azimuth (angle round to the east from north+, radians),
* return hour angle (radians), ha, and declination (radians), dec.
*/
aa_hadec (lat, alt, az, ha, dec)
float lat;
float alt, az;
float *ha, *dec;
{
aaha_aux (lat, az, alt, ha, dec);
}
/* given latitude (n+, radians), lat, hour angle (radians), ha, and declination
* (radians), dec,
* return altitude (up+, radians), alt, and
* azimuth (angle round to the east from north+, radians),
*/
hadec_aa (lat, ha, dec, alt, az)
float lat;
float ha, dec;
float *alt, *az;
{
aaha_aux (lat, ha, dec, az, alt);
}
/* the actual formula is the same for both transformation directions so
* do it here once for each way.
* N.B. all arguments are in radians.
*/
static
aaha_aux (lat, x, y, p, q)
float lat;
float x, y;
float *p, *q;
{
static float lastlat = -1000.;
static float sinlastlat, coslastlat;
float sy, cy;
float sx, cx;
float sq, cq;
float a;
float cp;
/* latitude doesn't change much, so try to reuse the sin and cos evals.
*/
if (lat != lastlat) {
sinlastlat = sin (lat);
coslastlat = cos (lat);
lastlat = lat;
}
sy = sin (y);
cy = cos (y);
sx = sin (x);
cx = cos (x);
/* define GOODATAN2 if atan2 returns full range -PI through +PI.
*/
#ifdef GOODATAN2
*q = asin ((sy*sinlastlat) + (cy*coslastlat*cx));
*p = atan2 (-cy*sx, -cy*cx*sinlastlat + sy*coslastlat);
#else
#define EPS (1e-20)
sq = (sy*sinlastlat) + (cy*coslastlat*cx);
*q = asin (sq);
cq = cos (*q);
a = coslastlat*cq;
if (a > -EPS && a < EPS)
a = a < 0 ? -EPS : EPS; /* avoid / 0 */
cp = (sy - (sinlastlat*sq))/a;
if (cp >= 1.0) /* the /a can be slightly > 1 */
*p = 0.0;
else if (cp <= -1.0)
*p = PI;
else
*p = acos ((sy - (sinlastlat*sq))/a);
if (sx>0) *p = 2.0*PI - *p;
#endif
}
xXx
echo extracting anomaly.c
cat > anomaly.c << 'xXx'
#include <stdio.h>
#include <math.h>
#include "astro.h"
#define TWOPI (2*PI)
/* given the mean anomaly, ma, and the eccentricity, s, of elliptical motion,
* find the true anomaly, *nu, and the eccentric anomaly, *ea.
* all angles in radians.
*/
anomaly (ma, s, nu, ea)
float ma, s;
float *nu, *ea;
{
float m, dla, fea;
m = ma-TWOPI*(int)(ma/TWOPI);
fea = m;
while (1) {
dla = fea-(s*sin(fea))-m;
if (fabs(dla)<1e-6)
break;
dla /= 1-(s*cos(fea));
fea -= dla;
}
*nu = 2*atan(sqrt((1+s)/(1-s))*tan(fea/2));
*ea = fea;
}
xXx
echo extracting astro.h
cat > astro.h << 'xXx'
#ifndef PI
#define PI 3.141592653589793
#endif
/* conversions among hours (of ra), degrees and radians. */
#define degrad(x) ((x)*PI/180.)
#define raddeg(x) ((x)*180./PI)
#define hrdeg(x) ((x)*15.)
#define deghr(x) ((x)/15.)
#define hrrad(x) degrad(hrdeg(x))
#define radhr(x) deghr(raddeg(x))
/* manifest names for planets.
* N.B. must cooincide with usage in pelement.c and plans.c.
*/
#define MERCURY 0
#define VENUS 1
#define MARS 2
#define JUPITER 3
#define SATURN 4
#define URANUS 5
#define NEPTUNE 6
#define PLUTO 7
xXx
echo extracting cal_mjd.c
cat > cal_mjd.c << 'xXx'
#include <stdio.h>
#include <math.h>
#include "astro.h"
/* given a date in months, mn, days, dy, years, yr,
* return the modified Julian date (number of days elapsed since 1900 jan 0.5),
* *mjd.
*/
cal_mjd (mn, dy, yr, mjd)
int mn, yr;
float dy;
float *mjd;
{
int b, d, m, y;
long c;
m = mn;
y = (yr < 0) ? yr + 1 : yr;
if (mn < 3) {
m += 12;
y -= 1;
}
if (yr < 1582 || yr == 1582 && (mn < 10 || mn == 10 && dy < 15))
b = 0;
else {
int a;
a = y/100;
b = 2 - a + a/4;
}
if (y < 0)
c = (long)((365.25*y) - 0.75) - 694025L;
else
c = (long)(365.25*y) - 694025L;
d = 30.6001*(m+1);
*mjd = b + c + d + dy - 0.5;
}
/* given the modified Julian date (number of days elapsed since 1900 jan 0.5,),
* mjd, return the calendar date in months, *mn, days, *dy, and years, *yr.
*/
mjd_cal (mjd, mn, dy, yr)
float mjd;
int *mn, *yr;
float *dy;
{
float d, f;
float i, a, b, ce, g;
d = mjd + 0.5;
i = floor(d);
f = d-i;
if (f == 1) {
f = 0;
i += 1;
}
if (i > -115860.0) {
a = floor((i/36524.25)+.9983573)+14;
i += 1 + a - floor(a/4.0);
}
b = floor((i/365.25)+.802601);
ce = i - floor((365.25*b)+.750001)+416;
g = floor(ce/30.6001);
*mn = g - 1;
*dy = ce - floor(30.6001*g)+f;
*yr = b + 1899;
if (g > 13.5)
*mn = g - 13;
if (*mn < 2.5)
*yr = b + 1900;
if (*yr < 1)
*yr -= 1;
}
/* given an mjd, set *dow to 0..6 according to which dayof the week it falls
* on (0=sunday) or set it to -1 if can't figure it out.
*/
mjd_dow (mjd, dow)
float mjd;
int *dow;
{
/* cal_mjd() uses Gregorian dates on or after Oct 15, 1582.
* (Pope Gregory XIII dropped 10 days, Oct 5..14, and improved the leap-
* year algorithm). however, Great Britian and the colonies did not
* adopt it until Sept 14, 1752 (they dropped 11 days, Sept 3-13,
* due to additional accumulated error). leap years before 1752 thus
* can not easily be accounted for from the cal_mjd() number...
*/
if (mjd < -53798.5) {
/* pre sept 14, 1752 too hard to correct */
*dow = -1;
return;
}
*dow = ((int)floor(mjd-.5) + 1) % 7; /* 1/1/1900 (mjd 0.5) is a Monday*/
if (*dow < 0)
*dow += 7;
}
/* given a mjd, return the the number of days in the month. */
mjd_dpm (mjd, ndays)
float mjd;
int *ndays;
{
static short dpm[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int m, y;
float d;
mjd_cal (mjd, &m, &d, &y);
*ndays = (m==2 && ((y%4==0 && y%100!=0)||y%400==0)) ? 29 : dpm[m-1];
}
xXx
echo extracting eq_ecl.c
cat > eq_ecl.c << 'xXx'
#include <stdio.h>
#include <math.h>
#include "astro.h"
#define EQtoECL 1
#define ECLtoEQ (-1)
/* given the modified Julian date, mjd, and an equitorial ra and dec, each in
* radians, find the corresponding geocentric ecliptic latitude, *lat, and
* longititude, *lng, also each in radians.
* the effects of nutation and the angle of the obliquity are included.
*/
eq_ecl (mjd, ra, dec, lat, lng)
float mjd, ra, dec;
float *lat, *lng;
{
ecleq_aux (EQtoECL, mjd, ra, dec, lng, lat);
}
/* given the modified Julian date, mjd, and a geocentric ecliptic latitude,
* *lat, and longititude, *lng, each in radians, find the corresponding
* equitorial ra and dec, also each in radians.
* the effects of nutation and the angle of the obliquity are included.
*/
ecl_eq (mjd, lat, lng, ra, dec)
float mjd, lat, lng;
float *ra, *dec;
{
ecleq_aux (ECLtoEQ, mjd, lng, lat, ra, dec);
}
static
ecleq_aux (sw, mjd, x, y, p, q)
int sw; /* +1 for eq to ecliptic, -1 for vv. */
float mjd, x, y; /* sw==1: x==ra, y==dec. sw==-1: x==lng, y==lat. */
float *p, *q; /* sw==1: p==lng, q==lat. sw==-1: p==ra, q==dec. */
{
static float lastmjd; /* last mjd calculated */
static float seps, ceps; /* sin and cos of mean obliquity */
float sx, cx, sy, cy, ty;
if (mjd != lastmjd) {
float deps, dpsi, eps;
obliquity (mjd, &eps); /* mean obliquity for date */
#ifdef NONUTATION
#define NONUTATION
deps = 0; /* checkout handler did not
* include nutation correction.
*/
#else
nutation (mjd, &deps, &dpsi); /* correctin due to nutation */
#endif
eps += deps; /* true obliquity for date */
seps = sin(eps);
ceps = cos(eps);
lastmjd = mjd;
}
sy = sin(y);
cy = cos(y); /* always non-negative */
if (fabs(cy)<1e-20) cy = 1e-20; /* insure > 0 */
ty = sy/cy;
cx = cos(x);
sx = sin(x);
*q = asin((sy*ceps)-(cy*seps*sx*sw));
*p = atan(((sx*ceps)+(ty*seps*sw))/cx);
if (cx<0) *p += PI; /* account for atan quad ambiguity */
range (p, 2*PI);
}
xXx
echo extracting moon.c
cat > moon.c << 'xXx'
#include <stdio.h>
#include <math.h>
#include "astro.h"
/* given the mjd, find the geocentric ecliptic longitude, lam, and latitude,
* bet, and horizontal parallax, hp for the moon.
* N.B. series for long and lat are good to about 10 and 3 arcseconds. however,
* math errors cause up to 100 and 30 arcseconds error, even if use double.
* why?? suspect highly sensitive nature of difference used to get m1..6.
* N.B. still need to correct for nutation. then for topocentric location
* further correct for parallax and refraction.
*/
moon (mjd, lam, bet, hp)
float mjd;
float *lam, *bet, *hp;
{
float t, t2;
float ld;
float ms;
float md;
float de;
float f;
float n;
float a, sa, sn, b, sb, c, sc, e, e2, l, g, w1, w2;
float m1, m2, m3, m4, m5, m6;
t = mjd/36525.;
t2 = t*t;
m1 = mjd/27.32158213;
m1 = 360.0*(m1-(int)m1);
m2 = mjd/365.2596407;
m2 = 360.0*(m2-(int)m2);
m3 = mjd/27.55455094;
m3 = 360.0*(m3-(int)m3);
m4 = mjd/29.53058868;
m4 = 360.0*(m4-(int)m4);
m5 = mjd/27.21222039;
m5 = 360.0*(m5-(int)m5);
m6 = mjd/6798.363307;
m6 = 360.0*(m6-(int)m6);
ld = 270.434164+m1-(.001133-.0000019*t)*t2;
ms = 358.475833+m2-(.00015+.0000033*t)*t2;
md = 296.104608+m3+(.009192+.0000144*t)*t2;
de = 350.737486+m4-(.001436-.0000019*t)*t2;
f = 11.250889+m5-(.003211+.0000003*t)*t2;
n = 259.183275-m6+(.002078+.000022*t)*t2;
a = degrad(51.2+20.2*t);
sa = sin(a);
sn = sin(degrad(n));
b = 346.56+(132.87-.0091731*t)*t;
sb = .003964*sin(degrad(b));
c = degrad(n+275.05-2.3*t);
sc = sin(c);
ld = ld+.000233*sa+sb+.001964*sn;
ms = ms-.001778*sa;
md = md+.000817*sa+sb+.002541*sn;
f = f+sb-.024691*sn-.004328*sc;
de = de+.002011*sa+sb+.001964*sn;
e = 1-(.002495+7.52e-06*t)*t;
e2 = e*e;
ld = degrad(ld);
ms = degrad(ms);
n = degrad(n);
de = degrad(de);
f = degrad(f);
md = degrad(md);
l = 6.28875*sin(md)+1.27402*sin(2*de-md)+.658309*sin(2*de)+
.213616*sin(2*md)-e*.185596*sin(ms)-.114336*sin(2*f)+
.058793*sin(2*(de-md))+.057212*e*sin(2*de-ms-md)+
.05332*sin(2*de+md)+.045874*e*sin(2*de-ms)+.041024*e*sin(md-ms);
l = l-.034718*sin(de)-e*.030465*sin(ms+md)+.015326*sin(2*(de-f))-
.012528*sin(2*f+md)-.01098*sin(2*f-md)+.010674*sin(4*de-md)+
.010034*sin(3*md)+.008548*sin(4*de-2*md)-e*.00791*sin(ms-md+2*de)-
e*.006783*sin(2*de+ms);
l = l+.005162*sin(md-de)+e*.005*sin(ms+de)+.003862*sin(4*de)+
e*.004049*sin(md-ms+2*de)+.003996*sin(2*(md+de))+
.003665*sin(2*de-3*md)+e*.002695*sin(2*md-ms)+
.002602*sin(md-2*(f+de))+e*.002396*sin(2*(de-md)-ms)-
.002349*sin(md+de);
l = l+e2*.002249*sin(2*(de-ms))-e*.002125*sin(2*md+ms)-
e2*.002079*sin(2*ms)+e2*.002059*sin(2*(de-ms)-md)-
.001773*sin(md+2*(de-f))-.001595*sin(2*(f+de))+
e*.00122*sin(4*de-ms-md)-.00111*sin(2*(md+f))+.000892*sin(md-3*de);
l = l-e*.000811*sin(ms+md+2*de)+e*.000761*sin(4*de-ms-2*md)+
e2*.000704*sin(md-2*(ms+de))+e*.000693*sin(ms-2*(md-de))+
e*.000598*sin(2*(de-f)-ms)+.00055*sin(md+4*de)+.000538*sin(4*md)+
e*.000521*sin(4*de-ms)+.000486*sin(2*md-de);
l = l+e2*.000717*sin(md-2*ms);
*lam = ld+degrad(l);
range (lam, 2*PI);
g = 5.12819*sin(f)+.280606*sin(md+f)+.277693*sin(md-f)+
.173238*sin(2*de-f)+.055413*sin(2*de+f-md)+.046272*sin(2*de-f-md)+
.032573*sin(2*de+f)+.017198*sin(2*md+f)+.009267*sin(2*de+md-f)+
.008823*sin(2*md-f)+e*.008247*sin(2*de-ms-f);
g = g+.004323*sin(2*(de-md)-f)+.0042*sin(2*de+f+md)+
e*.003372*sin(f-ms-2*de)+e*.002472*sin(2*de+f-ms-md)+
e*.002222*sin(2*de+f-ms)+e*.002072*sin(2*de-f-ms-md)+
e*.001877*sin(f-ms+md)+.001828*sin(4*de-f-md)-e*.001803*sin(f+ms)-
.00175*sin(3*f);
g = g+e*.00157*sin(md-ms-f)-.001487*sin(f+de)-e*.001481*sin(f+ms+md)+
e*.001417*sin(f-ms-md)+e*.00135*sin(f-ms)+.00133*sin(f-de)+
.001106*sin(f+3*md)+.00102*sin(4*de-f)+.000833*sin(f+4*de-md)+
.000781*sin(md-3*f)+.00067*sin(f+4*de-2*md);
g = g+.000606*sin(2*de-3*f)+.000597*sin(2*(de+md)-f)+
e*.000492*sin(2*de+md-ms-f)+.00045*sin(2*(md-de)-f)+
.000439*sin(3*md-f)+.000423*sin(f+2*(de+md))+
.000422*sin(2*de-f-3*md)-e*.000367*sin(ms+f+2*de-md)-
e*.000353*sin(ms+f+2*de)+.000331*sin(f+4*de);
g = g+e*.000317*sin(2*de+f-ms+md)+e2*.000306*sin(2*(de-ms)-f)-
.000283*sin(md+3*f);
w1 = .0004664*cos(n);
w2 = .0000754*cos(c);
*bet = degrad(g)*(1-w1-w2);
*hp = .950724+.051818*cos(md)+.009531*cos(2*de-md)+.007843*cos(2*de)+
.002824*cos(2*md)+.000857*cos(2*de+md)+e*.000533*cos(2*de-ms)+
e*.000401*cos(2*de-md-ms)+e*.00032*cos(md-ms)-.000271*cos(de)-
e*.000264*cos(ms+md)-.000198*cos(2*f-md);
*hp = *hp+.000173*cos(3*md)+.000167*cos(4*de-md)-e*.000111*cos(ms)+
.000103*cos(4*de-2*md)-.000084*cos(2*md-2*de)-
e*.000083*cos(2*de+ms)+.000079*cos(2*de+2*md)+.000072*cos(4*de)+
e*.000064*cos(2*de-ms+md)-e*.000063*cos(2*de+ms-md)+
e*.000041*cos(ms+de);
*hp = *hp+e*.000035*cos(2*md-ms)-.000033*cos(3*md-2*de)-
.00003*cos(md+de)-.000029*cos(2*(f-de))-e*.000029*cos(2*md+ms)+
e2*.000026*cos(2*(de-ms))-.000023*cos(2*(f-de)+md)+
e*.000019*cos(4*de-ms-md);
*hp = degrad(*hp);
}
xXx
echo extracting moonnf.c
cat > moonnf.c << 'xXx'
#include <stdio.h>
#include <math.h>
#include "astro.h"
#define unw(w,z) ((w)-floor((w)/(z))*(z))
/* given a modified Julian date, mjd, return the mjd of the new
* and full moons about then, mjdn and mjdf.
* TODO: exactly which ones does it find? eg:
* 5/28/1988 yields 5/15 and 5/31
* 5/29 6/14 6/29
*/
moonnf (mjd, mjdn, mjdf)
float mjd;
float *mjdn, *mjdf;
{
int mo, yr;
float dy;
float mjd0;
float k, tn, tf, t;
mjd_cal (mjd, &mo, &dy, &yr);
cal_mjd (1, 0., yr, &mjd0);
k = (yr-1900+((mjd-mjd0)/365))*12.3685;
k = floor(k+0.5);
tn = k/1236.85;
tf = (k+0.5)/1236.85;
t = tn;
m (t, k, mjdn);
t = tf;
k += 0.5;
m (t, k, mjdf);
}
static
m (t, k, mjd)
float t, k;
float *mjd;
{
float t2, a, a1, b, b1, c, ms, mm, f, ddjd;
t2 = t*t;
a = 29.53*k;
c = degrad(166.56+(132.87-9.173e-3*t)*t);
b = 5.8868e-4*k+(1.178e-4-1.55e-7*t)*t2+3.3e-4*sin(c)+7.5933E-1;
ms = 359.2242+360*unw(k/1.236886e1,1)-(3.33e-5+3.47e-6*t)*t2;
mm = 306.0253+360*unw(k/9.330851e-1,1)+(1.07306e-2+1.236e-5*t)*t2;
f = 21.2964+360*unw(k/9.214926e-1,1)-(1.6528e-3+2.39e-6*t)*t2;
ms = unw(ms,360);
mm = unw(mm,360);
f = unw(f,360);
ms = degrad(ms);
mm = degrad(mm);
f = degrad(f);
ddjd = (1.734e-1-3.93e-4*t)*sin(ms)+2.1e-3*sin(2*ms)
-4.068e-1*sin(mm)+1.61e-2*sin(2*mm)-4e-4*sin(3*mm)
+1.04e-2*sin(2*f)-5.1e-3*sin(ms+mm)-7.4e-3*sin(ms-mm)
+4e-4*sin(2*f+ms)-4e-4*sin(2*f-ms)-6e-4*sin(2*f+mm)
+1e-3*sin(2*f-mm)+5e-4*sin(ms+2*mm);
a1 = (int)a;
b = b+ddjd+(a-a1);
b1 = (int)b;
a = a1+b1;
b = b-b1;
*mjd = a + b;
}
xXx
echo extracting moonrs.c
cat > moonrs.c << 'xXx'
#include <stdio.h>
#include <math.h>
#include "astro.h"
#define PASSES 2
/* given the mjd and geographical latitude and longitude, lat and lng,
* find the ut and azimuth of moonrise, utcr and azr, and moonset, utcs and
* azs for the day of mjd. all angles are in radians.
* times are for the upper limb, including effects of refraction (a constant 34
* arcminutes), parallax, and nutation. accuracy is to nearest minute.
* the calculated times can be in error if they occur within about a half hour
* of utc midnight due to the algorithm's confusion about the date. the best
* way to verify it is to calculate the times for several days either side of
* the date to see whether the problem values conform to a smooth trend set
* by the others.
* possible values of status:
* 2: can't cope (such as geographical latitude very near +-90).
* 1: moon never rises/sets on date.
* 0: all ok.
* -1: moon is circumpolar.
* -2: possible error in near-midnight moonrise time; see above.
* -3: possible error in near-midnight moonset time; see above.
*/
moonrs (mjd, lat, lng, utcr, utcs, azr, azs, status)
float mjd, lat, lng;
float *utcr, *utcs;
float *azr, *azs;
int *status;
{
float lstr, lsts; /* local sidereal times of rising/setting */
float al = radhr(lng); /* time correction for longitude */
int midnight = 0; /* midnight caution */
float mjd0; /* start of mjd day */
float x; /* discarded tmp value */
float ut;
int pass;
mjd0 = floor(mjd+0.5)-0.5;
/* first approximation is to find rise/set times of a fixed object
* in the position of the moon at local midday.
*/
fixedmoonriset (mjd0+(12.0-al)/24.0, lat, &lstr, &lsts, &x, &x, status);
if (*status != 0) return;
/* find a better approximation to the rising circumstances based on two
* more passes, each using a "fixed" object at the moons location at
* previous approximation of the rise time.
*/
pass = 0;
while (1) {
gst_utc (mjd0, lstr, &ut);
if (++pass > PASSES)
break;
fixedmoonriset (mjd0+(ut-al)/24., lat, &lstr, &x, azr, &x, status);
if (*status != 0) return;
}
if (ut > 23.5 || ut < 0.5)
midnight = -2; /* moonrise caution near midnight */
*utcr = ut - (al * .9972696); /* allow for sidereal shift */
/* find a better approximation to the setting circumstances based on two
* more passes, each using a "fixed" object at the moons location at
* previous approximation of the setting time.
*/
pass = 0;
while (1) {
gst_utc (mjd0, lsts, &ut);
if (++pass > PASSES)
break;
fixedmoonriset (mjd0+(ut-al)/24., lat, &x, &lsts, &x, azs, status);
if (*status != 0) return;
}
if (ut > 23.5 || ut < 0.5)
midnight = -3; /* moonset caution near midnight */
*utcs = ut - (al * .9972696); /* allow for sidereal shift */
if (midnight)
*status = midnight; /* report caution if near midnight */
}
/* find the local rise/set sidereal times and azimuths of an object fixed
* at the ra/dec of the moon on the given mjd time as seen from lat.
*/
static
fixedmoonriset (mjd, lat, lstr, lsts, azr, azs, status)
float mjd, lat;
float *lstr, *lsts;
float *azr, *azs;
int *status;
{
float lam, bet, hp;
float deps, dpsi;
float dis;
float ra, dec;
/* find geocentric ecliptic location and equatorial horizontal parallax
* of moon at mjd.
*/
moon (mjd, &lam, &bet, &hp);
/* allow for nutation */
nutation (mjd, &deps, &dpsi);
lam += dpsi;
/* convert ecliptic to equatorial coords */
ecl_eq (mjd, bet, lam, &ra, &dec);
/* find local sidereal times of rise/set times/azimuths for given
* equatorial coords, allowing for
* .27249*sin(hp) parallax (hp is radius of earth from moon;
* .27249 is radius of moon from earth where
* the ratio is the dia_moon/dia_earth).
* 34' (9.8902e-3) nominal refraction
* hp nominal angular earth radius. subtract because
* tangential line-of-sight makes moon appear lower
* as move out from center of earth.
* TODO: do better at refraction; see fixedsunriset() in sunrs.c.
*/
dis = .27249*sin(hp) + 9.8902e-3 - hp;
riset (ra, dec, lat, dis, lstr, lsts, azr, azs, status);
}
xXx
echo extracting nutation.c
cat > nutation.c << 'xXx'
#include <stdio.h>
#include <math.h>
#include "astro.h"
/* given the modified JD, mjd, find the nutation in obliquity, *deps, and
* the nutation in longitude, *dpsi, each in radians.
*/
nutation (mjd, deps, dpsi)
float mjd;
float *deps, *dpsi;
{
static float lastmjd, lastdeps, lastdpsi;
float ls, ld; /* sun's mean longitude, moon's mean longitude */
float ms, md; /* sun's mean anomaly, moon's mean anomaly */
float nm; /* longitude of moon's ascending node */
float t, t2; /* number of Julian centuries of 36525 days since
* Jan 0.5 1900.
*/
float tls, tnm, tld; /* twice above */
double a, b; /* temps */
if (mjd == lastmjd) {
*deps = lastdeps;
*dpsi = lastdpsi;
return;
}
t = mjd/36525.;
t2 = t*t;
a = 100.0021358*t;
b = 360.*(a-(int)a);
ls = 279.697+.000303*t2+b;
a = 1336.855231*t;
b = 360.*(a-(int)a);
ld = 270.434-.001133*t2+b;
a = 99.99736056000026*t;
b = 360.*(a-(int)a);
ms = 358.476-.00015*t2+b;
a = 13255523.59*t;
b = 360.*(a-(int)a);
md = 296.105+.009192*t2+b;
a = 5.372616667*t;
b = 360.*(a-(int)a);
nm = 259.183+.002078*t2-b;
/* convert to radian forms for use with trig functions.
*/
tls = 2*degrad(ls);
nm = degrad(nm);
tnm = 2*degrad(nm);
ms = degrad(ms);
tld = 2*degrad(ld);
md = degrad(md);
/* find delta psi and eps, in arcseconds.
*/
lastdpsi = (-17.2327-.01737*t)*sin(nm)+(-1.2729-.00013*t)*sin(tls)
+.2088*sin(tnm)-.2037*sin(tld)+(.1261-.00031*t)*sin(ms)
+.0675*sin(md)-(.0497-.00012*t)*sin(tls+ms)
-.0342*sin(tld-nm)-.0261*sin(tld+md)+.0214*sin(tls-ms)
-.0149*sin(tls-tld+md)+.0124*sin(tls-nm)+.0114*sin(tld-md);
lastdeps = (9.21+.00091*t)*cos(nm)+(.5522-.00029*t)*cos(tls)
-.0904*cos(tnm)+.0884*cos(tld)+.0216*cos(tls+ms)
+.0183*cos(tld-nm)+.0113*cos(tld+md)-.0093*cos(tls-ms)
-.0066*cos(tls-nm);
/* convert to radians.
*/
lastdpsi = degrad(lastdpsi/3600);
lastdeps = degrad(lastdeps/3600);
lastmjd = mjd;
*deps = lastdeps;
*dpsi = lastdpsi;
}
xXx
echo extracting obliq.c
cat > obliq.c << 'xXx'
#include <stdio.h>
#include "astro.h"
/* given the modified Julian date, mjd, find the obliquity of the
* ecliptic, *eps, in radians.
*/
obliquity (mjd, eps)
float mjd;
float *eps;
{
static float lastmjd, lasteps;
if (mjd != lastmjd) {
float t;
t = mjd/36525.;
lasteps = degrad(2.345229444E1 - ((((-1.81E-3*t)+5.9E-3)*t+4.6845E1)*t)/3600.0);
lastmjd = mjd;
}
*eps = lasteps;
}
xXx
echo extracting parallax.c
cat > parallax.c << 'xXx'
#include <stdio.h>
#include <math.h>
#include "astro.h"
/* given true ha and dec, tha and tdec, the geographical latitude, phi, the
* height above sea-level (as a fraction of the earths radius, 6378.16km),
* ht, and the equatorial horizontal parallax, ehp, find the apparent
* ha and dec, aha and adec allowing for parallax.
* all angles in radians. ehp is the angle subtended at the body by the
* earth's equator.
*/
ta_par (tha, tdec, phi, ht, ehp, aha, adec)
float tha, tdec, phi, ht, ehp;
float *aha, *adec;
{
static float last_phi, last_ht, rsp, rcp;
float rp; /* distance to object in Earth radii */
float ctha;
float stdec, ctdec;
float tdtha, dtha;
float caha;
/* avoid calcs involving the same phi and ht */
if (phi != last_phi || ht != last_ht) {
float cphi, sphi, u;
cphi = cos(phi);
sphi = sin(phi);
u = atan(9.96647e-1*sphi/cphi);
rsp = (9.96647e-1*sin(u))+(ht*sphi);
rcp = cos(u)+(ht*cphi);
last_phi = phi;
last_ht = ht;
}
rp = 1/sin(ehp);
ctha = cos(tha);
stdec = sin(tdec);
ctdec = cos(tdec);
tdtha = (rcp*sin(tha))/((rp*ctdec)-(rcp*ctha));
dtha = atan(tdtha);
*aha = tha+dtha;
caha = cos(*aha);
range (aha, 2*PI);
*adec = atan(caha*(rp*stdec-rsp)/(rp*ctdec*ctha-rcp));
}
/* given the apparent ha and dec, aha and adec, the geographical latitude, phi,
* the height above sea-level (as a fraction of the earths radius, 6378.16km),
* ht, and the equatorial horizontal parallax, ehp, find the true ha and dec,
* tha and tdec allowing for parallax.
* all angles in radians. ehp is the angle subtended at the body by the
* earth's equator.
* uses ta_par() iteratively: find a set of true ha/dec that converts back
* to the given apparent ha/dec.
*/
at_par (aha, adec, phi, ht, ehp, tha, tdec)
float aha, adec, phi, ht, ehp;
float *tha, *tdec;
{
float nha, ndec; /* ha/dec corres. to current true guesses */
float eha, edec; /* error in ha/dec */
/* first guess for true is just the apparent */
*tha = aha;
*tdec = adec;
while (1) {
ta_par (*tha, *tdec, phi, ht, ehp, &nha, &ndec);
eha = aha - nha;
edec = adec - ndec;
if (fabs(eha)<1e-6 && fabs(edec)<1e-6)
break;
*tha += eha;
*tdec += edec;
}
}
xXx
echo extracting pelement.c
cat > pelement.c << 'xXx'
#include <stdio.h>
#include <math.h>
#include "astro.h"
/* this array contains polynomial coefficients to find the various orbital
* elements for the mean orbit at any instant in time for each major planet.
* the first five elements are in the form a0 + a1*t + a2*t**2 + a3*t**3,
* where t is the number of Julian centuries of 36525 Julian days since 1900
* Jan 0.5. the last three elements are constants.
*
* the orbital element (column) indeces are:
* [ 0- 3]: coefficients for mean longitude, in degrees;
* [ 4- 7]: coefficients for longitude of the perihelion, in degrees;
* [ 8-11]: coefficients for eccentricity;
* [12-15]: coefficients for inclination, in degrees;
* [16-19]: coefficients for longitude of the ascending node, in degrees;
* [20]: semi-major axis, in AU;
* [21]: angular diameter at 1 AU, in arcsec;
* [22]: standard visual magnitude, ie, the visual magnitude of the planet
* when at a distance of 1 AU from both the Sun and the Earth and
* with zero phase angle.
*
* the planent (row) indeces are:
* [0]: Mercury; [1]: Venus; [2]: Mars; [3]: Jupiter; [4]: Saturn;
* [5]: Uranus; [6]: Neptune; [7]: Pluto.
*/
#define NPELE (5*4 + 3) /* 4 coeffs for ea of 5 elems, + 3 constants */
static float elements[8][NPELE] = {
{ /* mercury... */
178.179078, 415.2057519, 3.011e-4, 0.0,
75.899697, 1.5554889, 2.947e-4, 0.0,
.20561421, 2.046e-5, 3e-8, 0.0,
7.002881, 1.8608e-3, -1.83e-5, 0.0,
47.145944, 1.1852083, 1.739e-4, 0.0,
.3870986, 6.74, -0.42
},
{ /* venus... */
342.767053, 162.5533664, 3.097e-4, 0.0,
130.163833, 1.4080361, -9.764e-4, 0.0,
6.82069e-3, -4.774e-5, 9.1e-8, 0.0,
3.393631, 1.0058e-3, -1e-6, 0.0,
75.779647, .89985, 4.1e-4, 0.0,
.7233316, 16.92, -4.4
},
{ /* mars... */
293.737334, 53.17137642, 3.107e-4, 0.0,
3.34218203e2, 1.8407584, 1.299e-4, -1.19e-6,
9.33129e-2, 9.2064e-5, 7.7e-8, 0.0,
1.850333, -6.75e-4, 1.26e-5, 0.0,
48.786442, .7709917, -1.4e-6, -5.33e-6,
1.5236883, 9.36, -1.52
},
{ /* jupiter... */
238.049257, 8.434172183, 3.347e-4, -1.65e-6,
1.2720972e1, 1.6099617, 1.05627e-3, -3.43e-6,
4.833475e-2, 1.6418e-4, -4.676e-7, -1.7e-9,
1.308736, -5.6961e-3, 3.9e-6, 0.0,
99.443414, 1.01053, 3.5222e-4, -8.51e-6,
5.202561, 196.74, -9.4
},
{ /* saturn... */
266.564377, 3.398638567, 3.245e-4, -5.8e-6,
9.1098214e1, 1.9584158, 8.2636e-4, 4.61e-6,
5.589232e-2, -3.455e-4, -7.28e-7, 7.4e-10,
2.492519, -3.9189e-3, -1.549e-5, 4e-8,
112.790414, .8731951, -1.5218e-4, -5.31e-6,
9.554747, 165.6, -8.88
},
{ /* uranus... */
244.19747, 1.194065406, 3.16e-4, -6e-7,
1.71548692e2, 1.4844328, 2.372e-4, -6.1e-7,
4.63444e-2, -2.658e-5, 7.7e-8, 0.0,
.772464, 6.253e-4, 3.95e-5, 0.0,
73.477111, .4986678, 1.3117e-3, 0.0,
19.21814, 65.8, -7.19
},
{ /* neptune... */
84.457994, .6107942056, 3.205e-4, -6e-7,
4.6727364e1, 1.4245744, 3.9082e-4, -6.05e-7,
8.99704e-3, 6.33e-6, -2e-9, 0.0,
1.779242, -9.5436e-3, -9.1e-6, 0.0,
130.681389, 1.098935, 2.4987e-4, -4.718e-6,
30.10957, 62.2, -6.87
},
{ /* pluto...(osculating 1984 jan 21) */
95.3113544, .3980332167, 0.0, 0.0,
224.017, 0.0, 0.0, 0.0,
.25515, 0.0, 0.0, 0.0,
17.1329, 0.0, 0.0, 0.0,
110.191, 0.0, 0.0, 0.0,
39.8151, 8.2, -1.0
}
};
/* given a modified Julian date, mjd, return the elements for the mean orbit
* at that instant of all the major planets, together with their
* mean daily motions in longitude, angular diameter and standard visual
* magnitude.
* plan[i][j] contains all the values for all the planets at mjd, such that
* i = 0..7: mercury, venus, mars, jupiter, saturn, unranus, neptune, pluto;
* j = 0..8: mean longitude, mean daily motion in longitude, longitude of
* the perihelion, eccentricity, inclination, longitude of the ascending
* node, length of the semi-major axis, angular diameter from 1 AU, and
* the standard visual magnitude (see elements[][] comment, above).
*/
pelement (mjd, plan)
float mjd;
float plan[8][9];
{
register float *ep, *pp;
register float t = mjd/36525.;
float aa;
int planet, i;
for (planet = 0; planet < 8; planet++) {
ep = elements[planet];
pp = plan[planet];
aa = ep[1]*t;
pp[0] = ep[0] + 360.*(aa-(int)aa) + (ep[3]*t + ep[2])*t*t;
range (pp, 360.);
pp[1] = (ep[1]*9.856263e-3) + (ep[2] + ep[3])/36525;
for (i = 4; i < 20; i += 4)
pp[i/4+1] = ((ep[i+3]*t + ep[i+2])*t + ep[i+1])*t + ep[i+0];
pp[6] = ep[20];
pp[7] = ep[21];
pp[8] = ep[22];
}
}
xXx
echo extracting plans.c
cat > plans.c << 'xXx'
#include <stdio.h>
#include <math.h>
#include "astro.h"
#define TWOPI (2*PI)
#define mod2PI(x) ((x) - (int)((x)/TWOPI)*TWOPI)
/* given a modified Julian date, mjd, and a planet, p, find:
* lpd0: heliocentric longitude,
* psi0: heliocentric latitude,
* rp0: distance from the sun to the planet,
* rho0: distance from the Earth to the planet,
* none corrected for light time, ie, they are the true values for the
* given instant.
* lam: geocentric ecliptic longitude,
* bet: geocentric ecliptic latitude,
* each corrected for light time, ie, they are the apparent values as
* seen from the center of the Earth for the given instant.
* dia: angular diameter in arcsec at 1 AU,
* mag: visual magnitude when 1 AU from sun and earth at 0 phase angle.
*
* all angles are in radians, all distances in AU.
* the mean orbital elements are found by calling pelement(), then mutual
* perturbation corrections are applied as necessary.
*
* corrections for nutation and abberation must be made by the caller. The RA
* and DEC calculated from the fully-corrected ecliptic coordinates are then
* the apparent geocentric coordinates. Further corrections can be made, if
* required, for atmospheric refraction and geocentric parallax although the
* intrinsic error herein of about 10 arcseconds is usually the dominant
* error at this stage.
* TODO: combine the several intermediate expressions when get a good compiler.
*/
plans (mjd, p, lpd0, psi0, rp0, rho0, lam, bet, dia, mag)
float mjd;
int p;
float *lpd0, *psi0, *rp0, *rho0, *lam, *bet, *dia, *mag;
{
static float plan[8][9];
static lastmjd = -10000;
float dl; /* perturbation correction for longitude */
float dr; /* " orbital radius */
float dml; /* " mean longitude */
float ds; /* " eccentricity */
float dm; /* " mean anomaly */
float da; /* " semi-major axis */
float dhl; /* " heliocentric longitude */
float lsn, rsn; /* true geocentric longitude of sun and sun-earth rad */
float mas; /* mean anomaly of the sun */
float re; /* radius of earth's orbit */
float lg; /* longitude of earth */
float map[8]; /* array of mean anomalies for each planet */
float lpd, psi, rp, rho;
float ll, sll, cll;
float t;
float dt;
int pass;
int j;
float s, ma;
float nu, ea;
float lp, om;
float lo, slo, clo;
float inc, y;
float spsi, cpsi;
float rpd;
/* only need to fill in plan[] once for a given mjd */
if (mjd != lastmjd) {
pelement (mjd, plan);
lastmjd = mjd;
}
dt = 0;
t = mjd/36525.;
sun (mjd, &lsn, &rsn);
masun (mjd, &mas);
re = rsn;
lg = lsn+PI;
/* first find the true position of the planet at mjd.
* then repeat a second time for a slightly different time based
* on the position found in the first pass to account for light-travel
* time.
*/
for (pass = 0; pass < 2; pass++) {
for (j = 0; j < 8; j++)
map[j] = degrad(plan[j][0]-plan[j][2]-dt*plan[j][1]);
/* set initial corrections to 0.
* then modify as necessary for the planet of interest.
*/
dl = 0;
dr = 0;
dml = 0;
ds = 0;
dm = 0;
da = 0;
dhl = 0;
switch (p) {
case MERCURY:
p_mercury (map, &dl, &dr);
break;
case VENUS:
p_venus (t, mas, map, &dl, &dr, &dml, &dm);
break;
case MARS:
p_mars (mas, map, &dl, &dr, &dml, &dm);
break;
case JUPITER:
p_jupiter (t, plan[p][3], &dml, &ds, &dm, &da);
break;
case SATURN:
p_saturn (t, plan[p][3], &dml, &ds, &dm, &da, &dhl);
break;
case URANUS:
p_uranus (t, plan[p][3], &dl, &dr, &dml, &ds, &dm, &da, &dhl);
break;
case NEPTUNE:
p_neptune (t, plan[p][3], &dl, &dr, &dml, &ds, &dm, &da, &dhl);
break;
case PLUTO:
/* no perturbation theory for pluto */
break;
}
s = plan[p][3]+ds;
ma = map[p]+dm;
anomaly (ma, s, &nu, &ea);
rp = (plan[p][6]+da)*(1-s*s)/(1+s*cos(nu));
lp = raddeg(nu)+plan[p][2]+raddeg(dml-dm);
lp = degrad(lp);
om = degrad(plan[p][5]);
lo = lp-om;
slo = sin(lo);
clo = cos(lo);
inc = degrad(plan[p][4]);
rp = rp+dr;
spsi = slo*sin(inc);
y = slo*cos(inc);
psi = asin(spsi)+dhl;
spsi = sin(psi);
lpd = atan(y/clo)+om+degrad(dl);
if (clo<0) lpd += PI;
if (lpd>TWOPI) lpd -= TWOPI;
cpsi = cos(psi);
rpd = rp*cpsi;
ll = lpd-lg;
rho = sqrt(re*re+rp*rp-2*re*rp*cpsi*cos(ll));
/* when we view a planet we see it in the position it occupied
* dt hours ago, where rho is the distance between it and earth,
* in AU. use this as the new time for the next pass.
*/
dt = rho*5.775518e-3;
if (pass == 0) {
/* save heliocentric coordinates after first pass since, being
* true, they are NOT to be corrected for light-travel time.
*/
*lpd0 = lpd;
*psi0 = psi;
*rp0 = rp;
*rho0 = rho;
}
}
sll = sin(ll);
cll = cos(ll);
if (p < MARS)
*lam = atan(-1*rpd*sll/(re-rpd*cll))+lg+PI;
else
*lam = atan(re*sll/(rpd-re*cll))+lpd;
range (lam, TWOPI);
*bet = atan(rpd*spsi*sin(*lam-lpd)/(cpsi*re*sll));
*dia = plan[p][7];
*mag = plan[p][8];
}
/* set auxilliary variables used for jupiter, saturn, uranus, and neptune */
static
aux_jsun (t, j1, j2, j3, j4, j5, j6)
float t;
float *j1, *j2, *j3, *j4, *j5, *j6;
{
*j1 = t/5+0.1;
*j2 = mod2PI(4.14473+5.29691e1*t);
*j3 = mod2PI(4.641118+2.132991e1*t);
*j4 = mod2PI(4.250177+7.478172*t);
*j5 = 5 * *j3 - 2 * *j2;
*j6 = 2 * *j2 - 6 * *j3 + 3 * *j4;
}
/* find the mean anomaly of the sun at mjd.
* this is the same as that used in sun() but when it was converted to C it
* was not known it would be required outside that routine.
* TODO: add an argument to sun() to return mas and eliminate this routine.
*/
static
masun (mjd, mas)
float mjd;
float *mas;
{
float t, t2;
float a, b;
t = mjd/36525;
t2 = t*t;
a = 9.999736042e1*t;
b = 360.*(a-(int)a);
*mas = degrad (3.5847583e2-(1.5e-4+3.3e-6*t)*t2+b);
}
/* perturbations for mercury */
static
p_mercury (map, dl, dr)
float map[];
float *dl, *dr;
{
*dl = 2.04e-3*cos(5*map[2-1]-2*map[1-1]+2.1328e-1)+
1.03e-3*cos(2*map[2-1]-map[1-1]-2.8046)+
9.1e-4*cos(2*map[3]-map[1-1]-6.4582e-1)+
7.8e-4*cos(5*map[2-1]-3*map[1-1]+1.7692e-1);
*dr = 7.525e-6*cos(2*map[3]-map[1-1]+9.25251e-1)+
6.802e-6*cos(5*map[2-1]-3*map[1-1]-4.53642)+
5.457e-6*cos(2*map[2-1]-2*map[1-1]-1.24246)+
3.569e-6*cos(5*map[2-1]-map[1-1]-1.35699);
}
/* ....venus */
static
p_venus (t, mas, map, dl, dr, dml, dm)
float t, mas, map[];
float *dl, *dr, *dml, *dm;
{
*dml = degrad (7.7e-4*sin(4.1406+t*2.6227));
*dm = *dml;
*dl = 3.13e-3*cos(2*mas-2*map[2-1]-2.587)+
1.98e-3*cos(3*mas-3*map[2-1]+4.4768e-2)+
1.36e-3*cos(mas-map[2-1]-2.0788)+
9.6e-4*cos(3*mas-2*map[2-1]-2.3721)+
8.2e-4*cos(map[3]-map[2-1]-3.6318);
*dr = 2.2501e-5*cos(2*mas-2*map[2-1]-1.01592)+
1.9045e-5*cos(3*mas-3*map[2-1]+1.61577)+
6.887e-6*cos(map[3]-map[2-1]-2.06106)+
5.172e-6*cos(mas-map[2-1]-5.08065e-1)+
3.62e-6*cos(5*mas-4*map[2-1]-1.81877)+
3.283e-6*cos(4*mas-4*map[2-1]+1.10851)+
3.074e-6*cos(2*map[3]-2*map[2-1]-9.62846e-1);
}
/* ....mars */
static
p_mars (mas, map, dl, dr, dml, dm)
float mas, map[];
float *dl, *dr, *dml, *dm;
{
float a;
a = 3*map[3]-8*map[2]+4*mas;
*dml = degrad (-1*(1.133e-2*sin(a)+9.33e-3*cos(a)));
*dm = *dml;
*dl = 7.05e-3*cos(map[3]-map[2]-8.5448e-1)+
6.07e-3*cos(2*map[3]-map[2]-3.2873)+
4.45e-3*cos(2*map[3]-2*map[2]-3.3492)+
3.88e-3*cos(mas-2*map[2]+3.5771e-1)+
2.38e-3*cos(mas-map[2]+6.1256e-1)+
2.04e-3*cos(2*mas-3*map[2]+2.7688)+
1.77e-3*cos(3*map[2]-map[2-1]-1.0053)+
1.36e-3*cos(2*mas-4*map[2]+2.6894)+
1.04e-3*cos(map[3]+3.0749e-1);
*dr = 5.3227e-5*cos(map[3]-map[2]+7.17864e-1)+
5.0989e-5*cos(2*map[3]-2*map[2]-1.77997)+
3.8278e-5*cos(2*map[3]-map[2]-1.71617)+
1.5996e-5*cos(mas-map[2]-9.69618e-1)+
1.4764e-5*cos(2*mas-3*map[2]+1.19768)+
8.966e-6*cos(map[3]-2*map[2]+7.61225e-1)+
7.914e-6*cos(3*map[3]-2*map[2]-2.43887)+
7.004e-6*cos(2*map[3]-3*map[2]-1.79573)+
6.62e-6*cos(mas-2*map[2]+1.97575)+
4.93e-6*cos(3*map[3]-3*map[2]-1.33069)+
4.693e-6*cos(3*mas-5*map[2]+3.32665)+
4.571e-6*cos(2*mas-4*map[2]+4.27086)+
4.409e-6*cos(3*map[3]-map[2]-2.02158);
}
/* ....jupiter */
static
p_jupiter (t, s, dml, ds, dm, da)
float t, s;
float *dml, *ds, *dm, *da;
{
float dp;
float j1, j2, j3, j4, j5, j6, j7;
float sj3, cj3, s2j3, c2j3;
float sj5, cj5, s2j5;
float sj6;
float sj7, cj7, s2j7, c2j7, s3j7, c3j7, s4j7, c4j7, c5j7;
aux_jsun (t, &j1, &j2, &j3, &j4, &j5, &j6);
j7 = j3-j2;
sj3 = sin(j3);
cj3 = cos(j3);
s2j3 = sin(2*j3);
c2j3 = cos(2*j3);
sj5 = sin(j5);
cj5 = cos(j5);
s2j5 = sin(2*j5);
sj6 = sin(j6);
sj7 = sin(j7);
cj7 = cos(j7);
s2j7 = sin(2*j7);
c2j7 = cos(2*j7);
s3j7 = sin(3*j7);
c3j7 = cos(3*j7);
s4j7 = sin(4*j7);
c4j7 = cos(4*j7);
c5j7 = cos(5*j7);
*dml = (3.31364e-1-(1.0281e-2+4.692e-3*j1)*j1)*sj5+
(3.228e-3-(6.4436e-2-2.075e-3*j1)*j1)*cj5-
(3.083e-3+(2.75e-4-4.89e-4*j1)*j1)*s2j5+
2.472e-3*sj6+1.3619e-2*sj7+1.8472e-2*s2j7+6.717e-3*s3j7+
2.775e-3*s4j7+6.417e-3*s2j7*sj3+
(7.275e-3-1.253e-3*j1)*sj7*sj3+
2.439e-3*s3j7*sj3-(3.5681e-2+1.208e-3*j1)*sj7*cj3-
3.767e-3*c2j7*sj3-(3.3839e-2+1.125e-3*j1)*cj7*sj3-
4.261e-3*s2j7*cj3+
(1.161e-3*j1-6.333e-3)*cj7*cj3+
2.178e-3*cj3-6.675e-3*c2j7*cj3-2.664e-3*c3j7*cj3-
2.572e-3*sj7*s2j3-3.567e-3*s2j7*s2j3+2.094e-3*cj7*c2j3+
3.342e-3*c2j7*c2j3;
*dml = degrad(*dml);
*ds = (3606+(130-43*j1)*j1)*sj5+(1289-580*j1)*cj5-6764*sj7*sj3-
1110*s2j7*sj3-224*s3j7*sj3-204*sj3+(1284+116*j1)*cj7*sj3+
188*c2j7*sj3+(1460+130*j1)*sj7*cj3+224*s2j7*cj3-817*cj3+
6074*cj3*cj7+992*c2j7*cj3+
508*c3j7*cj3+230*c4j7*cj3+108*c5j7*cj3-
(956+73*j1)*sj7*s2j3+448*s2j7*s2j3+137*s3j7*s2j3+
(108*j1-997)*cj7*s2j3+480*c2j7*s2j3+148*c3j7*s2j3+
(99*j1-956)*sj7*c2j3+490*s2j7*c2j3+
158*s3j7*c2j3+179*c2j3+(1024+75*j1)*cj7*c2j3-
437*c2j7*c2j3-132*c3j7*c2j3;
*ds *= 1e-7;
dp = (7.192e-3-3.147e-3*j1)*sj5-4.344e-3*sj3+
(j1*(1.97e-4*j1-6.75e-4)-2.0428e-2)*cj5+
3.4036e-2*cj7*sj3+(7.269e-3+6.72e-4*j1)*sj7*sj3+
5.614e-3*c2j7*sj3+2.964e-3*c3j7*sj3+3.7761e-2*sj7*cj3+
6.158e-3*s2j7*cj3-
6.603e-3*cj7*cj3-5.356e-3*sj7*s2j3+2.722e-3*s2j7*s2j3+
4.483e-3*cj7*s2j3-2.642e-3*c2j7*s2j3+4.403e-3*sj7*c2j3-
2.536e-3*s2j7*c2j3+5.547e-3*cj7*c2j3-2.689e-3*c2j7*c2j3;
*dm = *dml-(degrad(dp)/s);
*da = 205*cj7-263*cj5+693*c2j7+312*c3j7+147*c4j7+299*sj7*sj3+
181*c2j7*sj3+204*s2j7*cj3+111*s3j7*cj3-337*cj7*cj3-
111*c2j7*cj3;
*da *= 1e-6;
}
/* ....saturn */
static
p_saturn (t, s, dml, ds, dm, da, dhl)
float t, s;
float *dml, *ds, *dm, *da, *dhl;
{
float dp;
float j1, j2, j3, j4, j5, j6, j7, j8;
float sj3, cj3, s2j3, c2j3, s3j3, c3j3, s4j3, c4j3;
float sj5, cj5, s2j5, c2j5;
float sj6;
float sj7, cj7, s2j7, c2j7, s3j7, c3j7, s4j7, c4j7, c5j7, s5j7;
float s2j8, c2j8, s3j8, c3j8;
aux_jsun (t, &j1, &j2, &j3, &j4, &j5, &j6);
j7 = j3-j2;
sj3 = sin(j3);
cj3 = cos(j3);
s2j3 = sin(2*j3);
c2j3 = cos(2*j3);
sj5 = sin(j5);
cj5 = cos(j5);
s2j5 = sin(2*j5);
sj6 = sin(j6);
sj7 = sin(j7);
cj7 = cos(j7);
s2j7 = sin(2*j7);
c2j7 = cos(2*j7);
s3j7 = sin(3*j7);
c3j7 = cos(3*j7);
s4j7 = sin(4*j7);
c4j7 = cos(4*j7);
c5j7 = cos(5*j7);
s3j3 = sin(3*j3);
c3j3 = cos(3*j3);
s4j3 = sin(4*j3);
c4j3 = cos(4*j3);
c2j5 = cos(2*j5);
s5j7 = sin(5*j7);
j8 = j4-j3;
s2j8 = sin(2*j8);
c2j8 = cos(2*j8);
s3j8 = sin(3*j8);
c3j8 = cos(3*j8);
*dml = 7.581e-3*s2j5-7.986e-3*sj6-1.48811e-1*sj7-4.0786e-2*s2j7-
(8.14181e-1-(1.815e-2-1.6714e-2*j1)*j1)*sj5-
(1.0497e-2-(1.60906e-1-4.1e-3*j1)*j1)*cj5-1.5208e-2*s3j7-
6.339e-3*s4j7-6.244e-3*sj3-1.65e-2*s2j7*sj3+
(8.931e-3+2.728e-3*j1)*sj7*sj3-5.775e-3*s3j7*sj3+
(8.1344e-2+3.206e-3*j1)*cj7*sj3+1.5019e-2*c2j7*sj3+
(8.5581e-2+2.494e-3*j1)*sj7*cj3+1.4394e-2*c2j7*cj3+
(2.5328e-2-3.117e-3*j1)*cj7*cj3+
6.319e-3*c3j7*cj3+6.369e-3*sj7*s2j3+9.156e-3*s2j7*s2j3+
7.525e-3*s3j8*s2j3-5.236e-3*cj7*c2j3-7.736e-3*c2j7*c2j3-
7.528e-3*c3j8*c2j3;
*dml = degrad(*dml);
*ds = (-7927+(2548+91*j1)*j1)*sj5+(13381+(1226-253*j1)*j1)*cj5+
(248-121*j1)*s2j5-(305+91*j1)*c2j5+412*s2j7+12415*sj3+
(390-617*j1)*sj7*sj3+(165-204*j1)*s2j7*sj3+26599*cj7*sj3-
4687*c2j7*sj3-1870*c3j7*sj3-821*c4j7*sj3-
377*c5j7*sj3+497*c2j8*sj3+(163-611*j1)*cj3-
12696*sj7*cj3-4200*s2j7*cj3-1503*s3j7*cj3-619*s4j7*cj3-
268*s5j7*cj3-(282+1306*j1)*cj7*cj3+(-86+230*j1)*c2j7*cj3+
461*s2j8*cj3-350*s2j3+(2211-286*j1)*sj7*s2j3-
2208*s2j7*s2j3-568*s3j7*s2j3-346*s4j7*s2j3-
(2780+222*j1)*cj7*s2j3+(2022+263*j1)*c2j7*s2j3+248*c3j7*s2j3+
242*s3j8*s2j3+467*c3j8*s2j3-490*c2j3-(2842+279*j1)*sj7*c2j3+
(128+226*j1)*s2j7*c2j3+224*s3j7*c2j3+
(-1594+282*j1)*cj7*c2j3+(2162-207*j1)*c2j7*c2j3+
561*c3j7*c2j3+343*c4j7*c2j3+469*s3j8*c2j3-242*c3j8*c2j3-
205*sj7*s3j3+262*s3j7*s3j3+208*cj7*c3j3-271*c3j7*c3j3-
382*c3j7*s4j3-376*s3j7*c4j3;
*ds *= 1e-7;
dp = (7.7108e-2+(7.186e-3-1.533e-3*j1)*j1)*sj5-7.075e-3*sj7+
(4.5803e-2-(1.4766e-2+5.36e-4*j1)*j1)*cj5-7.2586e-2*cj3-
7.5825e-2*sj7*sj3-2.4839e-2*s2j7*sj3-8.631e-3*s3j7*sj3-
1.50383e-1*cj7*cj3+2.6897e-2*c2j7*cj3+1.0053e-2*c3j7*cj3-
(1.3597e-2+1.719e-3*j1)*sj7*s2j3+1.1981e-2*s2j7*c2j3-
(7.742e-3-1.517e-3*j1)*cj7*s2j3+
(1.3586e-2-1.375e-3*j1)*c2j7*c2j3-
(1.3667e-2-1.239e-3*j1)*sj7*c2j3+
(1.4861e-2+1.136e-3*j1)*cj7*c2j3-
(1.3064e-2+1.628e-3*j1)*c2j7*c2j3;
*dm = *dml-(degrad(dp)/s);
*da = 572*sj5-1590*s2j7*cj3+2933*cj5-647*s3j7*cj3+33629*cj7-
344*s4j7*cj3-3081*c2j7+2885*cj7*cj3-1423*c3j7+
(2172+102*j1)*c2j7*cj3-671*c4j7+296*c3j7*cj3-320*c5j7-
267*s2j7*s2j3+1098*sj3-778*cj7*s2j3-2812*sj7*sj3+
495*c2j7*s2j3+688*s2j7*sj3+250*c3j7*s2j3-393*s3j7*sj3-
856*sj7*c2j3-228*s4j7*sj3+441*s2j7*c2j3+2138*cj7*sj3+
296*c2j7*c2j3-999*c2j7*sj3+211*c3j7*c2j3-642*c3j7*sj3-
427*sj7*s3j3-325*c4j7*sj3+398*s3j7*s3j3-890*cj3+
344*cj7*c3j3+2206*sj7*cj3-427*c3j7*c3j3;
*da *= 1e-6;
*dhl = 7.47e-4*cj7*sj3+1.069e-3*cj7*cj3+2.108e-3*s2j7*s2j3+
1.261e-3*c2j7*s2j3+1.236e-3*s2j7*c2j3-2.075e-3*c2j7*c2j3;
*dhl = degrad(*dhl);
}
/* ....uranus */
static
p_uranus (t, s, dl, dr, dml, ds, dm, da, dhl)
float t, s;
float *dl, *dr, *dml, *ds, *dm, *da, *dhl;
{
float dp;
float j1, j2, j3, j4, j5, j6;
float j8, j9, j10, j11, j12;
float sj4, cj4, s2j4, c2j4;
float sj9, cj9, s2j9, c2j9;
float sj11, cj11;
aux_jsun (t, &j1, &j2, &j3, &j4, &j5, &j6);
j8 = mod2PI(1.46205+3.81337*t);
j9 = 2*j8-j4;
sj9 = sin(j9);
cj9 = cos(j9);
s2j9 = sin(2*j9);
c2j9 = cos(2*j9);
j10 = j4-j2;
j11 = j4-j3;
j12 = j8-j4;
*dml = (8.64319e-1-1.583e-3*j1)*sj9+(8.2222e-2-6.833e-3*j1)*cj9+
3.6017e-2*s2j9-3.019e-3*c2j9+8.122e-3*sin(j6);
*dml = degrad(*dml);
dp = 1.20303e-1*sj9+6.197e-3*s2j9+(1.9472e-2-9.47e-4*j1)*cj9;
*dm = *dml-(degrad(dp)/s);
*ds = (163*j1-3349)*sj9+20981*cj9+1311*c2j9;
*ds *= 1e-7;
*da = -3.825e-3*cj9;
*dl = (1.0122e-2-9.88e-4*j1)*sin(j4+j11)+
(-3.8581e-2+(2.031e-3-1.91e-3*j1)*j1)*cos(j4+j11)+
(3.4964e-2-(1.038e-3-8.68e-4*j1)*j1)*cos(2*j4+j11)+
5.594e-3*sin(j4+3*j12)-1.4808e-2*sin(j10)-
5.794e-3*sin(j11)+2.347e-3*cos(j11)+9.872e-3*sin(j12)+
8.803e-3*sin(2*j12)-4.308e-3*sin(3*j12);
sj11 = sin(j11);
cj11 = cos(j11);
sj4 = sin(j4);
cj4 = cos(j4);
s2j4 = sin(2*j4);
c2j4 = cos(2*j4);
*dhl = (4.58e-4*sj11-6.42e-4*cj11-5.17e-4*cos(4*j12))*sj4-
(3.47e-4*sj11+8.53e-4*cj11+5.17e-4*sin(4*j11))*cj4+
4.03e-4*(cos(2*j12)*s2j4+sin(2*j12)*c2j4);
*dhl = degrad(*dhl);
*dr = -25948+4985*cos(j10)-1230*cj4+3354*cos(j11)+904*cos(2*j12)+
894*(cos(j12)-cos(3*j12))+(5795*cj4-1165*sj4+1388*c2j4)*sj11+
(1351*cj4+5702*sj4+1388*s2j4)*cos(j11);
*dr *= 1e-6;
}
/* ....neptune */
static
p_neptune (t, s, dl, dr, dml, ds, dm, da, dhl)
float t, s;
float *dl, *dr, *dml, *ds, *dm, *da, *dhl;
{
float dp;
float j1, j2, j3, j4, j5, j6;
float j8, j9, j10, j11, j12;
float sj8, cj8;
float sj9, cj9, s2j9, c2j9;
float s2j12, c2j12;
aux_jsun (t, &j1, &j2, &j3, &j4, &j5, &j6);
j8 = mod2PI(1.46205+3.81337*t);
j9 = 2*j8-j4;
sj9 = sin(j9);
cj9 = cos(j9);
s2j9 = sin(2*j9);
c2j9 = cos(2*j9);
j10 = j8-j2;
j11 = j8-j3;
j12 = j8-j4;
*dml = (1.089e-3*j1-5.89833e-1)*sj9+(4.658e-3*j1-5.6094e-2)*cj9-
2.4286e-2*s2j9;
*dml = degrad(*dml);
dp = 2.4039e-2*sj9-2.5303e-2*cj9+6.206e-3*s2j9-5.992e-3*c2j9;
*dm = *dml-(degrad(dp)/s);
*ds = 4389*sj9+1129*s2j9+4262*cj9+1089*c2j9;
*ds *= 1e-7;
*da = 8189*cj9-817*sj9+781*c2j9;
*da *= 1e-6;
s2j12 = sin(2*j12);
c2j12 = cos(2*j12);
sj8 = sin(j8);
cj8 = cos(j8);
*dl = -9.556e-3*sin(j10)-5.178e-3*sin(j11)+2.572e-3*s2j12-
2.972e-3*c2j12*sj8-2.833e-3*s2j12*cj8;
*dhl = 3.36e-4*c2j12*sj8+3.64e-4*s2j12*cj8;
*dhl = degrad(*dhl);
*dr = -40596+4992*cos(j10)+2744*cos(j11)+2044*cos(j12)+1051*c2j12;
*dr *= 1e-6;
}
xXx
echo extracting precess.c
cat > precess.c << 'xXx'
#include <stdio.h>
#include <math.h>
#include "astro.h"
/* corrects ra and dec, both in radians, for precession from epoch 1 to epoch 2.
* the epochs are given by their modified JDs, mjd1 and mjd2, respectively.
* N.B. ra and dec are modifed IN PLACE.
*/
precess (mjd1, mjd2, ra, dec)
float mjd1, mjd2; /* initial and final epoch modified JDs */
float *ra, *dec; /* ra/dec for mjd1 in, for mjd2 out */
{
static float lastmjd1, lastmjd2;
static float m, n, nyrs;
float dra, ddec; /* ra and dec corrections */
if (mjd1 != lastmjd1 || mjd2 != lastmjd2) {
float t1, t2; /* Julian centuries of 36525 days since Jan .5 1900 */
float m1, n1; /* "constants" for t1 */
float m2, n2; /* "constants" for t2 */
t1 = mjd1/36525.;
t2 = mjd2/36525.;
m1 = 3.07234+(1.86e-3*t1);
n1 = 20.0468-(8.5e-3*t1);
m2 = 3.07234+(1.86e-3*t2);
n2 = 20.0468-(8.5e-3*t2);
m = (m1+m2)/2; /* average m for the two epochs */
n = (n1+n2)/2; /* average n for the two epochs */
nyrs = (mjd2-mjd1)/365.2425;
lastmjd1 = mjd1;
lastmjd2 = mjd2;
}
dra = (m+(n*sin(*ra)*tan(*dec)/15))*7.272205e-5*nyrs;
ddec = n*cos(*ra)*4.848137e-6*nyrs;
*ra += dra;
*dec += ddec;
range (ra, 2*PI);
}
xXx
echo extracting refract.c
cat > refract.c << 'xXx'
#include <stdio.h>
#include <math.h>
#include "astro.h"
/* correct the true altitude, ta, for refraction to the apparent altitude, aa,
* each in radians, given the local atmospheric pressure, pr, in mbars, and
* the temperature, tr, in degrees C.
*/
refract (pr, tr, ta, aa)
float pr, tr;
float ta;
float *aa;
{
float r; /* refraction correction*/
if (ta >= degrad(15.)) {
/* model for altitudes at least 15 degrees above horizon */
r = 7.888888e-5*pr/((273+tr)*tan(ta));
} else if (ta > degrad(-5.)) {
/* hairier model for altitudes at least -5 and below 15 degrees */
float a, b, tadeg = raddeg(ta);
a = ((2e-5*tadeg+1.96e-2)*tadeg+1.594e-1)*pr;
b = (273+tr)*((8.45e-2*tadeg+5.05e-1)*tadeg+1);
r = degrad(a/b);
} else {
/* do nothing if more than 5 degrees below horizon.
*/
r = 0;
}
*aa = ta + r;
}
/* correct the apparent altitude, aa, for refraction to the true altitude, ta,
* each in radians, given the local atmospheric pressure, pr, in mbars, and
* the temperature, tr, in degrees C.
*/
unrefract (pr, tr, aa, ta)
float pr, tr;
float aa;
float *ta;
{
float err;
float appar;
float true;
/* iterative solution: search for the true that refracts to the
* given apparent.
* since refract() is discontinuous at -5 degrees, there is a range
* of apparent altitudes between about -4.5 and -5 degrees that are
* not invertable (the graph of ap vs. true has a vertical step at
* true = -5). thus, the iteration just oscillates if it gets into
* this region. if this happens the iteration is forced to abort.
* of course, this makes unrefract() discontinuous too.
*/
true = aa;
do {
refract (pr, tr, true, &appar);
err = appar - aa;
true -= err;
} while (fabs(err) >= 1e-6 && true > degrad(-5));
*ta = true;
}
xXx
echo extracting riset.c
cat > riset.c << 'xXx'
#include <stdio.h>
#include <math.h>
#include "astro.h"
/* given the true geocentric ra and dec of an object, in radians, the observer's
* latitude in radians, and a horizon displacement correction, dis, in radians
* find the local sidereal times and azimuths of rising and setting, lstr/s
* and azr/s, in radians, respectively.
* dis is the vertical displacement from the true position of the horizon. it
* is positive if the apparent position is higher than the true position.
* said another way, it is positive if the shift causes the object to spend
* longer above the horizon. for example, atmospheric refraction is typically
* assumed to produce a vertical shift of 34 arc minutes at the horizon; dis
* would then take on the value +9.89e-3 (radians). On the other hand, if
* your horizon has hills such that your apparent horizon is, say, 1 degree
* above sea level, you would allow for this by setting dis to -1.75e-2
* (radians).
* status: 0: normal; 1: never rises; -1: circumpolar; 2: trouble.
*/
riset (ra, dec, lat, dis, lstr, lsts, azr, azs, status)
float ra, dec;
float lat, dis;
float *lstr, *lsts;
float *azr, *azs;
int *status;
{
static float lastlat = 0, slat = 0, clat = 1.0;
float dec1, sdec, cdec, tdec;
float psi, spsi, cpsi;
float h, dh, ch; /* hr angle, delta and cos */
/* avoid needless sin/cos since latitude doesn't change often */
if (lat != lastlat) {
clat = cos(lat);
slat = sin(lat);
lastlat = lat;
}
/* can't cope with objects very near the celestial pole nor if we
* are located very near the earth's poles.
*/
cdec = cos(dec);
if (fabs(cdec*clat) < 1e-10) {
/* trouble */
*status = 2;
return;
}
cpsi = slat/cdec;
if (cpsi>1.0) cpsi = 1.0;
else if (cpsi<-1.0) cpsi = -1.0;
psi = acos(cpsi);
spsi = sin(psi);
dh = dis*spsi;
dec1 = dec + (dis*cpsi);
sdec = sin(dec1);
tdec = tan(dec1);
ch = (-1*slat*tdec)/clat;
if (ch < -1) {
/* circumpolar */
*status = -1;
return;
}
if (ch > 1) {
/* never rises */
*status = 1;
return;
}
*status = 0;
h = acos(ch)+dh;
*lstr = 24+radhr(ra-h);
*lsts = radhr(ra+h);
range (lstr, 24.0);
range (lsts, 24.0);
*azr = acos(sdec/clat);
range (azr, 2*PI);
*azs = 2*PI - *azr;
}
xXx
echo extracting sex_dec.c
cat > sex_dec.c << 'xXx'
/* given hours (or degrees), hd, minutes, m, and seconds, s,
* return decimal hours (or degrees), *d.
* in the case of hours (angles) < 0, only the first non-zero element should
* be negative.
*/
sex_dec (hd, m, s, d)
int hd, m, s;
float *d;
{
int sign = 1;
if (hd < 0) {
sign = -1;
hd = -hd;
} else if (m < 0) {
sign = -1;
m = -m;
} else if (s < 0) {
sign = -1;
s = -s;
}
*d = ((s/60.0 + m)/60.0 + hd) * sign;
}
/* given decimal hours (or degrees), d.
* return nearest hours (or degrees), *hd, minutes, *m, and seconds, *s,
* each always non-negative; *isneg is set to 1 if d is < 0, else to 0.
*/
dec_sex (d, hd, m, s, isneg)
float d;
int *hd, *m, *s, *isneg;
{
float min;
if (d < 0) {
*isneg = 1;
d = -d;
} else
*isneg = 0;
*hd = (int)d;
min = (d - *hd)*60.;
*m = (int)min;
*s = (int)((min - *m)*60. + 0.5);
if (*s == 60) {
if ((*m += 1) == 60) {
*hd += 1;
*m = 0;
}
*s = 0;
}
/* no negative 0's */
if (*hd == 0 && *m == 0 && *s == 0)
*isneg = 0;
}
/* insure 0 <= *v < r.
*/
range (v, r)
float *v, r;
{
while (*v < 0) *v += r;
while (*v >= r) *v -= r;
}
xXx
echo extracting sun.c
cat > sun.c << 'xXx'
#include <stdio.h>
#include <math.h>
#include "astro.h"
/* given the modified JD, mjd, return the true geocentric ecliptic longitude
* of the sun for the mean equinox of the date, *lsn, in radians, and the
* sun-earth distance, *rsn, in AU. (the true ecliptic latitude is never more
* than 1.2 arc seconds and so may be taken to be a constant 0.)
* if the APPARENT ecliptic longitude is required, correct the longitude for
* nutation to the true equinox of date and for aberration (light travel time,
* approximately -9.27e7/186000/(3600*24*365)*2*pi = -9.93e-5 radians).
*/
sun (mjd, lsn, rsn)
float mjd;
float *lsn, *rsn;
{
float t, t2;
float ls, ms; /* mean longitude and mean anomoay */
float s, nu, ea; /* eccentricity, true anomaly, eccentric anomaly */
double a, b, a1, b1, c1, d1, e1, h1, dl, dr;
t = mjd/36525.;
t2 = t*t;
a = 100.0021359*t;
b = 360.*(a-(int)a);
ls = 279.69668+.0003025*t2+b;
a = 99.99736042000039*t;
b = 360*(a-(int)a);
ms = 358.47583-(.00015+.0000033*t)*t2+b;
s = .016751-.0000418*t-1.26e-07*t2;
anomaly (degrad(ms), s, &nu, &ea);
a = 62.55209472000015*t;
b = 360*(a-(int)a);
a1 = degrad(153.23+b);
a = 125.1041894*t;
b = 360*(a-(int)a);
b1 = degrad(216.57+b);
a = 91.56766028*t;
b = 360*(a = (int)a);
c1 = degrad(312.69+b);
a = 1236.853095*t;
b = 360*(a-(int)a);
d1 = degrad(350.74-.00144*t2+b);
e1 = degrad(231.19+20.2*t);
a = 183.1353208*t;
b = 360*(a-(int)a);
h1 = degrad(353.4+b);
dl = .00134*cos(a1)+.00154*cos(b1)+.002*cos(c1)+.00179*sin(d1)+
.00178*sin(e1);
dr = 5.43e-06*sin(a1)+1.575e-05*sin(b1)+1.627e-05*sin(c1)+
3.076e-05*cos(d1)+9.27e-06*sin(h1);
*lsn = nu+degrad(ls-ms+dl);
*rsn = 1.0000002*(1-s*cos(ea))+dr;
range (lsn, 2*PI);
}
xXx
echo extracting sunrs.c
cat > sunrs.c << 'xXx'
#include <stdio.h>
#include <math.h>
#include "astro.h"
/* given the modified julian date, mjd, geographical latitude, lat, and
* longitude, lng, each in radians with west lng < 0, and a horizon
* displacement, dis, find the utc times of sunrise, utcr, and sunset, utcs,
* and the azimuths of sunrise, azr, and sunset, azs. all angles in radians;
* azimuths are E of N.
* times are for the upper limb, including effects of nutation and aberration.
* displacement is additional amount added to suns altitude compared to its
* true location; see riset.c for more discussion. it can be used to
* account for irregular horizons, various refraction models, even times
* of twilight. eg, refraction to a level horizon is often taken to be about
* 32/2(sun's semi-diameter) + 34(nominal refraction) = 50 arc minutes.
* better is:
* unrefract (pre, temp, 0.0, &a); /* true alt of upper limb
* a -= SUN_DIAM; /* true alt of sun center
* also used to find astro twilight by calling with dis of 18 degrees.
* status:
* 2: error
* 1: never rises
* 0: normal
* -1: circumpolar
*/
sunrs (mjd, lat, lng, dis, utcr, utcs, azr, azs, status)
float mjd, lat, lng, dis;
float *utcr, *utcs;
float *azr, *azs;
int *status;
{
float lstr, lsts; /* local sidereal times of rising/setting */
float al = radhr(lng); /* time correction for longitude */
float tmp1, tmp2; /* tmp */
float mjd0, t;
mjd0 = floor(mjd+0.5)-0.5; /* insure mjd0 is greenwich start of day */
/* first approximation is to find rise/set times of a fixed object
* in the position of the sun at local midday. the sun is not
* fixed but moves about a degree per day so these are then refined.
*/
fixedsunriset(mjd0+(12.-al)/24.,lat,dis,&lstr,&lsts,&tmp1,&tmp2,status);
if (*status != 0) return;
/* find a better approximation to the rising circumstances based on a
* fixed object at the suns location at the first approximation of the
* rise time.
* N.B. more iterations are less than sp float precision.
*/
gst_utc (mjd0, lstr, &t);
fixedsunriset(mjd0+(t-al)/24.,lat,dis,&lstr,&tmp1,azr,&tmp2,status);
if (*status != 0) return;
gst_utc (mjd0, lstr, utcr);
*utcr -= al*.9972696; /* allow for sideral shift */
/* find a better approximation to the setting circumstances based on a
* fixed object at the suns location at the first approximation of the
* setting time.
*/
gst_utc (mjd0, lsts, &t);
fixedsunriset (mjd0+(t-al)/24.,lat,dis,&tmp1,&lsts,&tmp2,azs,status);
if (*status != 0) return;
gst_utc (mjd0, lsts, utcs);
*utcs -= al*.9972696; /* allow for sideral shift */
}
/* find the local rise/set sidereal times and azimuths of an object fixed
* at the ra/dec of the sun on the given mjd time as seen from lat.
*/
static
fixedsunriset (mjd, lat, dis, lstr, lsts, azr, azs, status)
float mjd, lat, dis;
float *lstr, *lsts;
float *azr, *azs;
int *status;
{
float lsn, rsn;
float deps, dpsi;
float ra, dec;
/* find ecliptic position of sun at mjd */
sun (mjd, &lsn, &rsn);
/* allow for 20.4" aberation and nutation */
nutation (mjd, &deps, &dpsi);
lsn += dpsi - degrad(20.4/3600.0);
/* convert ecliptic to equatorial coords */
ecl_eq (mjd, 0.0, lsn, &ra, &dec);
/* find circumstances for given horizon displacement */
riset (ra, dec, lat, dis, lstr, lsts, azr, azs, status);
}
xXx
echo extracting utc_gst.c
cat > utc_gst.c << 'xXx'
/* given a modified julian date, mjd, and a universally coordinated time, utc,
* return greenwich mean siderial time, *gst.
*/
utc_gst (mjd, utc, gst)
float mjd;
float utc;
float *gst;
{
float tnaught();
static float lastmjd;
static float t0;
if (mjd != lastmjd) {
t0 = tnaught (mjd);
lastmjd = mjd;
}
*gst = 1.002737908*utc + t0;
range (gst, 24.0);
}
/* given a modified julian date, mjd, and a greenwich mean siderial time, gst,
* return universally coordinated time, *utc.
*/
gst_utc (mjd, gst, utc)
float mjd;
float gst;
float *utc;
{
float tnaught();
static float lastmjd;
static float t0;
if (mjd != lastmjd) {
t0 = tnaught (mjd);
range (&t0, 24.0);
lastmjd = mjd;
}
*utc = gst - t0;
range (utc, 24.0);
*utc *= .9972695677;
}
static float
tnaught (mjd)
float mjd; /* julian days since 1900 jan 0.5 */
{
float dmjd;
int m, y;
float d;
float t, t0;
mjd_cal (mjd, &m, &d, &y);
cal_mjd (1, 0., y, &dmjd);
t = dmjd/36525;
t0 = 6.57098e-2 * (mjd - dmjd) -
(24 - (6.6460656 + (5.1262e-2 + (t * 2.581e-5))*t) -
(2400 * (t - (((float)y - 1900)/100))));
return (t0);
}
xXx
More information about the Comp.sources.misc
mailing list