home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Starbase One Astronomy & Space Collection
/
STARBASE_ONE.ISO
/
a94
/
disk10
/
ephem42.exe
/
RISET_C.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-09-13
|
9KB
|
276 lines
/* find rise and set circumstances, ie, riset_cir() and related functions. */
#include <stdio.h>
#include <math.h>
#include "astro.h"
#include "circum.h"
#include "screen.h" /* just for SUN and MOON */
#define TRACE(x) {FILE *fp = fopen("trace","a"); fprintf x; fclose(fp);}
#define STDREF degrad(34./60.) /* nominal horizon refraction amount */
#define TWIREF degrad(18.) /* twilight horizon displacement */
#define TMACC (15./3600.) /* convergence accuracy, hours */
/* find where and when a body, p, will rise and set and
* its transit circumstances. all times are local, angles rads e of n.
* return 0 if just returned same stuff as previous call, else 1 if new.
* status is set from the RS_* #defines in circum.h.
* also used to find astro twilight by calling with dis of 18 degrees.
*/
riset_cir (p, np, force, hzn, ltr, lts, ltt, azr, azs, altt, status)
int p; /* one of the body defines in astro.h or screen.h */
Now *np;
int force; /* set !=0 to force computations */
int hzn; /* STDHZN or ADPHZN or TWILIGHT */
double *ltr, *lts; /* local rise and set times */
double *ltt; /* local transit time */
double *azr, *azs; /* local rise and set azimuths, rads e of n */
double *altt; /* local altitude at transit */
int *status; /* one or more of the RS_* defines */
{
typedef struct {
Now l_now;
double l_ltr, l_lts, l_ltt, l_azr, l_azs, l_altt;
int l_hzn;
int l_status;
} Last;
/* must be in same order as the astro.h/screen.h #define's */
static Last last[NOBJ] = {
{NOMJD}, {NOMJD}, {NOMJD}, {NOMJD}, {NOMJD}, {NOMJD},
{NOMJD}, {NOMJD}, {NOMJD}, {NOMJD}, {NOMJD}, {NOMJD}
};
Last *lp;
int new;
lp = last + p;
if (!force && same_cir (np, &lp->l_now) && same_lday (np, &lp->l_now)
&& lp->l_hzn == hzn) {
*ltr = lp->l_ltr;
*lts = lp->l_lts;
*ltt = lp->l_ltt;
*azr = lp->l_azr;
*azs = lp->l_azs;
*altt = lp->l_altt;
*status = lp->l_status;
new = 0;
} else {
*status = 0;
iterative_riset (p, np, hzn, ltr, lts, ltt, azr, azs, altt, status);
lp->l_ltr = *ltr;
lp->l_lts = *lts;
lp->l_ltt = *ltt;
lp->l_azr = *azr;
lp->l_azs = *azs;
lp->l_altt = *altt;
lp->l_status = *status;
lp->l_hzn = hzn;
lp->l_now = *np;
new = 1;
}
return (new);
}
static
iterative_riset (p, np, hzn, ltr, lts, ltt, azr, azs, altt, status)
int p;
Now *np;
int hzn;
double *ltr, *lts, *ltt; /* local times of rise, set and transit */
double *azr, *azs, *altt;/* local azimuths of rise, set and transit altitude */
int *status;
{
#define MAXPASSES 6
double lstr, lsts, lstt; /* local sidereal times of rising/setting */
double mjd0; /* mjd estimates of rise/set event */
double lnoon; /* mjd of local noon */
double x; /* discarded tmp value */
Now n; /* just used to call now_lst() */
double lst; /* lst at local noon */
double diff, lastdiff; /* iterative improvement to mjd0 */
int pass;
int rss;
/* first approximation is to find rise/set times of a fixed object
* in its position at local noon.
*/
lnoon = mjd_day(mjd - tz/24.0) + (12.0 + tz)/24.0; /*mjd of local noon*/
n.n_mjd = lnoon;
n.n_lng = lng;
now_lst (&n, &lst); /* lst at local noon */
mjd0 = lnoon;
stationary_riset (p,mjd0,np,hzn,&lstr,&lsts,&lstt,&x,&x,&x,&rss);
chkrss:
switch (rss) {
case 0: break;
case 1: *status = RS_NEVERUP; return;
case -1: *status = RS_CIRCUMPOLAR; goto transit;
default: *status = RS_ERROR; return;
}
/* find a better approximation to the rising circumstances based on
* more passes, each using a "fixed" object at the location at
* previous approximation of the rise time.
*/
lastdiff = 1000.0;
for (pass = 1; pass < MAXPASSES; pass++) {
diff = (lstr - lst)*SIDRATE; /* next guess at rise time wrt noon */
if (diff > 12.0)
diff -= 24.0*SIDRATE; /* not tomorrow, today */
else if (diff < -12.0)
diff += 24.0*SIDRATE; /* not yesterday, today */
mjd0 = lnoon + diff/24.0; /* next guess at mjd of rise */
stationary_riset (p,mjd0,np,hzn,&lstr,&x,&x,azr,&x,&x,&rss);
if (rss != 0) goto chkrss;
if (fabs (diff - lastdiff) < TMACC)
break;
lastdiff = diff;
}
if (pass == MAXPASSES)
*status |= RS_NORISE; /* didn't converge - no rise today */
else {
*ltr = 12.0 + diff;
if (p != MOON &&
(*ltr <= 24.0*(1.0-SIDRATE) || *ltr >= 24.0*SIDRATE))
*status |= RS_2RISES;
}
/* find a better approximation to the setting circumstances based on
* more passes, each using a "fixed" object at the location at
* previous approximation of the set time.
*/
lastdiff = 1000.0;
for (pass = 1; pass < MAXPASSES; pass++) {
diff = (lsts - lst)*SIDRATE; /* next guess at set time wrt noon */
if (diff > 12.0)
diff -= 24.0*SIDRATE; /* not tomorrow, today */
else if (diff < -12.0)
diff += 24.0*SIDRATE; /* not yesterday, today */
mjd0 = lnoon + diff/24.0; /* next guess at mjd of set */
stationary_riset (p,mjd0,np,hzn,&x,&lsts,&x,&x,azs,&x,&rss);
if (rss != 0) goto chkrss;
if (fabs (diff - lastdiff) < TMACC)
break;
lastdiff = diff;
}
if (pass == MAXPASSES)
*status |= RS_NOSET; /* didn't converge - no set today */
else {
*lts = 12.0 + diff;
if (p != MOON &&
(*lts <= 24.0*(1.0-SIDRATE) || *lts >= 24.0*SIDRATE))
*status |= RS_2SETS;
}
transit:
/* find a better approximation to the transit circumstances based on
* more passes, each using a "fixed" object at the location at
* previous approximation of the transit time.
*/
lastdiff = 1000.0;
for (pass = 1; pass < MAXPASSES; pass++) {
diff = (lstt - lst)*SIDRATE; /*next guess at transit time wrt noon*/
if (diff > 12.0)
diff -= 24.0*SIDRATE; /* not tomorrow, today */
else if (diff < -12.0)
diff += 24.0*SIDRATE; /* not yesterday, today */
mjd0 = lnoon + diff/24.0; /* next guess at mjd of transit */
stationary_riset (p,mjd0,np,hzn,&x,&x,&lstt,&x,&x,altt,&rss);
if (fabs (diff - lastdiff) < TMACC)
break;
lastdiff = diff;
}
if (pass == MAXPASSES)
*status |= RS_NOTRANS; /* didn't converge - no transit today */
else {
*ltt = 12.0 + diff;
if (p != MOON &&
(*ltt <= 24.0*(1.0-SIDRATE) || *ltt >= 24.0*SIDRATE))
*status |= RS_2TRANS;
}
}
static
stationary_riset (p, mjd0, np, hzn, lstr, lsts, lstt, azr, azs, altt, status)
int p;
double mjd0;
Now *np;
int hzn;
double *lstr, *lsts, *lstt;
double *azr, *azs, *altt;
int *status;
{
extern void bye();
double dis;
Now n;
Sky s;
/* find object p's topocentric ra/dec at mjd0
* (this must include parallax)
*/
n = *np;
n.n_mjd = mjd0;
(void) body_cir (p, 0.0, &n, &s);
if (epoch != EOD)
precess (epoch, mjd0, &s.s_ra, &s.s_dec);
if (s.s_edist > 0) {
/* parallax, if we can */
double ehp, lst, ha;
if (p == MOON)
ehp = asin (6378.14/s.s_edist);
else
ehp = (2.*6378./146e6)/s.s_edist;
now_lst (&n, &lst);
ha = hrrad(lst) - s.s_ra;
ta_par (ha, s.s_dec, lat, height, ehp, &ha, &s.s_dec);
s.s_ra = hrrad(lst) - ha;
range (&s.s_ra, 2*PI);
}
switch (hzn) {
case STDHZN:
/* nominal atmospheric refraction.
* then add nominal moon or sun semi-diameter, as appropriate.
* other objects assumes to be negligibly small.
*/
dis = STDREF;
if (p == MOON || p == SUN)
dis += degrad (32./60./2.);
break;
case TWILIGHT:
if (p != SUN) {
f_msg ("Non-sun twilight bug!");
bye();
}
dis = TWIREF;
break;
case ADPHZN:
/* adaptive includes actual refraction conditions and also
* includes object's semi-diameter.
*/
unrefract (pressure, temp, 0.0, &dis);
dis = -dis;
dis += degrad(s.s_size/3600./2.0);
break;
}
riset (s.s_ra, s.s_dec, lat, dis, lstr, lsts, azr, azs, status);
transit (s.s_ra, s.s_dec, np, lstt, altt);
}
/* find when and how hi object at (r,d) is when it transits. */
static
transit (r, d, np, lstt, altt)
double r, d; /* ra and dec, rads */
Now *np; /* for refraction info */
double *lstt; /* local sidereal time of transit */
double *altt; /* local, refracted, altitude at time of transit */
{
*lstt = radhr(r);
*altt = PI/2 - lat + d;
if (*altt > PI/2)
*altt = PI - *altt;
refract (pressure, temp, *altt, altt);
}