downey@cs.umn.edu@dimed1.UUCP (08/31/90)
Posting-number: Volume 14, Issue 78 Submitted-by: downey@cs.umn.edu@dimed1.UUCP Archive-name: ephem-4.21/part03 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 3 (of 6)." # Contents: altmenus.c circum.c ephem.db plot.c version.c # Wrapped by allbery@uunet on Thu Aug 30 20:46:33 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'altmenus.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'altmenus.c'\" else echo shar: Extracting \"'altmenus.c'\" \(10867 characters\) sed "s/^X//" >'altmenus.c' <<'END_OF_FILE' X/* printing routines for the three alternative bottom half menus, X * "menu1", "menu2" and "menu3". X */ X X#include <stdio.h> X#include <math.h> X#include "astro.h" X#include "circum.h" X#include "screen.h" X Xstatic int altmenu = F_MNU1; /* which alternate menu is up; one of F_MNUi */ Xstatic int alt2_stdhzn; /* whether to use STDHZN (aot ADPHZN) horizon algthm */ Xstatic int alt3_geoc; /* whether to use geocentric (aot topocentric) vantage*/ X X/* table of screen rows given a body #define from astro/h or screen.h */ Xstatic short bodyrow[NOBJ] = { X R_MERCURY, R_VENUS, R_MARS, R_JUPITER, R_SATURN, X R_URANUS, R_NEPTUNE, R_PLUTO, R_SUN, R_MOON, R_OBJX, R_OBJY X}; X/* table of screen cols for third menu format, given body #define ... */ Xstatic short bodycol[NOBJ] = { X C_MERCURY, C_VENUS, C_MARS, C_JUPITER, C_SATURN, X C_URANUS, C_NEPTUNE, C_PLUTO, C_SUN, C_MOON, C_OBJX, C_OBJY X}; X X/* initialize altmenu; used by main from cracking the ephem startup file. X */ Xaltmenu_init (n) Xint n; X{ X altmenu = n; X} X X/* let op decide which alternate menu should be up, X * including any menu-specific setup they might require. X * return 0 if things changed to require updating the alt menu; else -1. X */ Xaltmenu_setup() X{ X static char *flds[5] = { X "Data menu", "Rise/Set menu", "Separations menu" X }; X int newmenu = altmenu, newhzn = alt2_stdhzn, newgeoc = alt3_geoc; X int new; X int fn = altmenu == F_MNU1 ? 0 : altmenu == F_MNU2 ? 1 : 2; X X ask: X flds[3]= newhzn ? "Standard hzn" : "Adaptive hzn"; X flds[4]= newgeoc? "Geocentric" : "Topocentric"; X X switch (popup (flds, fn, 5)) { X case 0: newmenu = F_MNU1; break; X case 1: newmenu = F_MNU2; break; X case 2: newmenu = F_MNU3; break; X case 3: newhzn ^= 1; fn = 3; goto ask; X case 4: newgeoc ^= 1; fn = 4; goto ask; X default: return (-1); X } X X new = 0; X if (newmenu != altmenu) { X altmenu = newmenu; X new++; X } X if (newhzn != alt2_stdhzn) { X alt2_stdhzn = newhzn; X if (newmenu == F_MNU2) X new++; X } X if (newgeoc != alt3_geoc) { X alt3_geoc = newgeoc; X if (newmenu == F_MNU3) X new++; X } X return (new ? 0 : -1); X} X X/* erase the info for the given planet */ Xalt_nobody (p) Xint p; X{ X f_eol (bodyrow[p], C_RA); X} X Xalt_body (b, force, np) Xint b; /* which body, ala astro.h and screen.h defines */ Xint force; /* if !0 then draw for sure, else just if changed since last */ XNow *np; X{ X switch (altmenu) { X case F_MNU1: alt1_body (b, force, np); break; X case F_MNU2: alt2_body (b, force, np); break; X case F_MNU3: alt3_body (b, force, np); break; X } X} X X/* draw the labels for the current alternate menu format */ Xalt_labels () X{ X switch (altmenu) { X case F_MNU1: alt1_labels (); break; X case F_MNU2: alt2_labels (); break; X case F_MNU3: alt3_labels (); break; X } X} X X/* erase the labels for the current alternate menu format */ Xalt_nolabels () X{ X int i; X X f_string (R_ALTM, C_ALTMV, " "); X for (i = R_PLANTAB; i < R_SUN; i++) X f_eol (i, C_RA); X} X Xalt_menumask() X{ X return (altmenu); X} X X/* handy function to return the next planet in the order in which they are X * displayed in the lower half of the screen. X * input is a given planet, return is the next planet. X * if input is not legal, then first planet is returned; when input is the X * last planet, then -1 is returned. X * typical usage is something like: X * for (p = nxtbody(-1); p != -1; p = nxtbody(p)) X */ Xnxtbody(p) Xint p; X{ X static short nxtpl[NOBJ] = { X VENUS, MARS, JUPITER, SATURN, URANUS, X NEPTUNE, PLUTO, OBJX, MOON, MERCURY, OBJY, -1 X }; X X if (p < MERCURY || p >= NOBJ) X return (SUN); X else X return (nxtpl[p]); X} X Xstatic Xalt1_labels() X{ X f_string (R_ALTM, C_ALTMV, " Planet Data"); X X f_string (R_PLANTAB, C_RA+2, "R.A."); X f_string (R_PLANTAB, C_DEC+2,"Dec"); X f_string (R_PLANTAB, C_AZ+2, "Az"); X f_string (R_PLANTAB, C_ALT+2,"Alt"); X f_string (R_PLANTAB, C_HLONG,"H Long"); X f_string (R_PLANTAB, C_HLAT, "H Lat"); X f_string (R_PLANTAB, C_EDIST,"Ea Dst"); X f_string (R_PLANTAB, C_SDIST,"Sn Dst"); X f_string (R_PLANTAB, C_ELONG,"Elong"); X f_string (R_PLANTAB, C_SIZE, "Size"); X f_string (R_PLANTAB, C_MAG, "VMag"); X f_string (R_PLANTAB, C_PHASE,"Phs"); X} X Xstatic Xalt2_labels() X{ X f_string (R_ALTM, C_ALTMV, "Rise/Set Info"); X X f_string (R_PLANTAB, C_RISETM-2, "Rise Time"); X f_string (R_PLANTAB, C_RISEAZ, "Rise Az"); X f_string (R_PLANTAB, C_TRANSTM-2, "Trans Time"); X f_string (R_PLANTAB, C_TRANSALT-1, "Trans Alt"); X f_string (R_PLANTAB, C_SETTM-1, "Set Time"); X f_string (R_PLANTAB, C_SETAZ, "Set Az"); X f_string (R_PLANTAB, C_TUP-1, "Hours Up"); X} X Xstatic Xalt3_labels() X{ X f_string (R_ALTM, C_ALTMV, " Separations"); X X f_string (R_PLANTAB, C_SUN, " Sun"); X f_string (R_PLANTAB, C_MOON, "Moon"); X f_string (R_PLANTAB, C_MERCURY, "Merc"); X f_string (R_PLANTAB, C_VENUS, "Venus"); X f_string (R_PLANTAB, C_MARS, "Mars"); X f_string (R_PLANTAB, C_JUPITER, " Jup"); X f_string (R_PLANTAB, C_SATURN, " Sat"); X f_string (R_PLANTAB, C_URANUS, "Uranus"); X f_string (R_PLANTAB, C_NEPTUNE, " Nep"); X f_string (R_PLANTAB, C_PLUTO, "Pluto"); X f_string (R_PLANTAB, C_OBJX, " X"); X f_string (R_PLANTAB, C_OBJY, " Y"); X} X X/* print body info in first menu format */ Xstatic Xalt1_body (p, force, np) Xint p; /* which body, as in astro.h/screen.h defines */ Xint force; /* whether to print for sure or only if things have changed */ XNow *np; X{ X Sky sky; X double as = plot_ison() || srch_ison() ? 0.0 : 60.0; X int row = bodyrow[p]; X X if (body_cir (p, as, np, &sky) || force) { X f_ra (row, C_RA, sky.s_ra); X f_angle (row, C_DEC, sky.s_dec); X if (sky.s_hlong != NOHELIO) { X f_angle (row, C_HLONG, sky.s_hlong); X if (p != SUN) X f_angle (row, C_HLAT, sky.s_hlat); X } X X if (p == MOON) { X /* distance is on km, show in miles */ X f_double (R_MOON, C_EDIST, "%6.0f", sky.s_edist/1.609344); X } else if (sky.s_edist > 0.0) { X /* show distance in au */ X f_double (row, C_EDIST,(sky.s_edist>=10.0)?"%6.3f":"%6.4f", X sky.s_edist); X } X if (sky.s_sdist > 0.0) X f_double (row, C_SDIST, (sky.s_sdist>=10.0)?"%6.3f":"%6.4f", X sky.s_sdist); X if (p != SUN) X f_double (row, C_ELONG, "%6.1f", sky.s_elong); X if (p != OBJX && p != OBJY) X f_double (row, C_SIZE, (p==MOON||p==SUN)?"%4.0f":"%4.1f", X sky.s_size); X f_double (row, C_MAG, (p==MOON||p==SUN)?"%4.0f":"%4.1f", X sky.s_mag); X if (sky.s_sdist > 0.0) { X /* some terminals scroll when write a char in low-right corner. X * TODO: is there a nicer way to handle this maybe? X */ X int col = row == NR ? C_PHASE - 1 : C_PHASE; X /* would just do this if Turbo-C 2.0 "%?.0f" worked: X * f_double (row, col, "%3.0f", sky.s_phase); X */ X f_int (row, col, "%3d", sky.s_phase); X } X } X X f_angle (row, C_AZ, sky.s_az); X f_angle (row, C_ALT, sky.s_alt); X} X X/* print body info in the second menu format */ Xstatic Xalt2_body (p, force, np) Xint p; /* which body, as in astro.h/screen.h defines */ Xint force; /* whether to print for sure or only if things have changed */ XNow *np; X{ X double ltr, lts, ltt, azr, azs, altt; X int row = bodyrow[p]; X int status; X double tmp; X int today_tup = 0; X X /* always recalc OBJX and Y since we don't know it's the same object */ X if (!riset_cir (p, np, p==OBJX || p==OBJY, alt2_stdhzn?STDHZN:ADPHZN, X <r, <s, <t, &azr, &azs, &altt, &status) && !force) X return; X X alt_nobody (p); X X if (status & RS_ERROR) { X /* can not find where body is! */ X f_string (row, C_RISETM, "?Error?"); X return; X } X if (status & RS_CIRCUMPOLAR) { X /* body is up all day */ X f_string (row, C_RISETM, "Circumpolar"); X if (status & RS_NOTRANS) X f_string (row, C_TRANSTM, "No transit"); X else { X f_mtime (row, C_TRANSTM, ltt); X if (status & RS_2TRANS) X f_char (row, C_TRANSTM+5, '+'); X f_angle (row, C_TRANSALT, altt); X } X f_string (row, C_TUP, "24:00"); /*f_mtime() changes to 0:00 */ X return; X } X if (status & RS_NEVERUP) { X /* body never up at all today */ X f_string (row, C_RISETM, "Never up"); X f_mtime (row, C_TUP, 0.0); X return; X } X X if (status & RS_NORISE) { X /* object does not rise as such today */ X f_string (row, C_RISETM, "Never rises"); X ltr = 0.0; /* for TUP */ X today_tup = 1; X } else { X f_mtime (row, C_RISETM, ltr); X if (status & RS_2RISES) { X /* object rises more than once today */ X f_char (row, C_RISETM+5, '+'); X } X f_angle (row, C_RISEAZ, azr); X } X X if (status & RS_NOTRANS) X f_string (row, C_TRANSTM, "No transit"); X else { X f_mtime (row, C_TRANSTM, ltt); X if (status & RS_2TRANS) X f_char (row, C_TRANSTM+5, '+'); X f_angle (row, C_TRANSALT, altt); X } X X if (status & RS_NOSET) { X /* object does not set as such today */ X f_string (row, C_SETTM, "Never sets"); X lts = 24.0; /* for TUP */ X today_tup = 1; X } else { X f_mtime (row, C_SETTM, lts); X if (status & RS_2SETS) X f_char (row, C_SETTM+5, '+'); X f_angle (row, C_SETAZ, azs); X } X X tmp = lts - ltr; X if (tmp < 0) X tmp = 24.0 + tmp; X f_mtime (row, C_TUP, tmp); X if (today_tup) X f_char (row, C_TUP+5, '+'); X} X X/* print body info in third menu format. this may be either the geocentric X * or topocentric angular separation between object p and each of the others. X * the latter, of course, includes effects of refraction and so can change X * quite rapidly near the time of each planets rise or set. X * for now, we don't save old values so we always redo everything and ignore X * the "force" argument. this isn't that bad since body_cir() has memory and X * will avoid most computations as we hit them again in the lower triangle. X * we are limited to only 5 columns per object. to make it fit, we display X * degrees:minutes if less than 100 degrees, otherwise just whole degrees. X */ X/*ARGSUSED*/ Xstatic Xalt3_body (p, force, np) Xint p; /* which body, as in astro.h/screen.h defines */ Xint force; /* whether to print for sure or only if things have changed */ XNow *np; X{ X int row = bodyrow[p]; X Sky skyp, skyq; X double spy, cpy, px, *qx, *qy; X int wantx = obj_ison(OBJX); X int wanty = obj_ison(OBJY); X double as = plot_ison() || srch_ison() ? 0.0 : 60.0; X int q; X X (void) body_cir (p, as, np, &skyp); X if (alt3_geoc) { X /* use ra for "x", dec for "y". */ X spy = sin (skyp.s_dec); X cpy = cos (skyp.s_dec); X px = skyp.s_ra; X qx = &skyq.s_ra; X qy = &skyq.s_dec; X } else { X /* use azimuth for "x", altitude for "y". */ X spy = sin (skyp.s_alt); X cpy = cos (skyp.s_alt); X px = skyp.s_az; X qx = &skyq.s_az; X qy = &skyq.s_alt; X } X for (q = nxtbody(-1); q != -1; q = nxtbody(q)) X if (q != p && (q != OBJX || wantx) && (q != OBJY || wanty)) { X double sep, dsep; X (void) body_cir (q, as, np, &skyq); X sep = acos(spy*sin(*qy) + cpy*cos(*qy)*cos(px-*qx)); X dsep = raddeg(sep); X if (dsep >= (100.0 - 1.0/60.0/2.0)) X f_int (row, bodycol[q], "%5d:", dsep); X else X f_angle (row, bodycol[q], sep); X } X} END_OF_FILE if test 10867 -ne `wc -c <'altmenus.c'`; then echo shar: \"'altmenus.c'\" unpacked with wrong size! fi # end of 'altmenus.c' fi if test -f 'circum.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'circum.c'\" else echo shar: Extracting \"'circum.c'\" \(10483 characters\) sed "s/^X//" >'circum.c' <<'END_OF_FILE' X/* fill in a Sky struct with all we know about each object. X *(the user defined objects are in obj.c) X */ X X#include <stdio.h> X#include <math.h> X#include "astro.h" X#include "circum.h" X#include "screen.h" /* just for SUN and MOON */ X X/* find body p's circumstances now. X * to save some time the caller may specify a desired accuracy, in arc seconds. X * if, based on its mean motion, it would not have moved this much since the X * last time we were called we only recompute altitude and azimuth and avoid X * recomputing the planet's heliocentric position. use 0.0 for best possible. X * we always recompute the user-defined objects' position regardless. X * return 0 if only alt/az changes, else 1 if all other stuff updated too. X * TODO: beware of fast retrograde motions. X */ Xbody_cir (p, as, np, sp) Xint p; Xdouble as; XNow *np; XSky *sp; X{ X typedef struct { X double l_dpas; /* mean days per arc second */ X Now l_now; /* when l_sky was found */ X double l_ra, l_dec; /* the eod, ie, unprecessed, ra/dec values */ X Sky l_sky; X } Last; X /* must be in same order as the astro.h object #define's */ X static Last last[8] = { X {.000068, {NOMJD}}, X {.00017, {NOMJD}}, X {.00053, {NOMJD}}, X {.0034, {NOMJD}}, X {.0092, {NOMJD}}, X {.027, {NOMJD}}, X {.046, {NOMJD}}, X {.069, {NOMJD}} X }; X Last objxlast, objylast; X double lst, alt, az; X double ehp, ha, dec; /* ehp: angular dia of earth from body */ X Last *lp; X int new; X X switch (p) { X case SUN: return (sun_cir (as, np, sp)); X case MOON: return (moon_cir (as, np, sp)); X case OBJX: lp = &objxlast; break; X case OBJY: lp = &objylast; break; X default: lp = last + p; break; X } X X /* if less than l_every days from last time for this planet X * just redo alt/az. X * ALWAYS redo objects x and y. X */ X if (p != OBJX && p != OBJY && same_cir (np, &lp->l_now) X && about_now (np, &lp->l_now, as*lp->l_dpas)) { X *sp = lp->l_sky; X new = 0; X } else { X double lpd0, psi0; /* heliocentric ecliptic long and lat */ X double rp0; /* dist from sun */ X double rho0; /* dist from earth */ X double lam, bet; /* geocentric ecliptic long and lat */ X double dia, mag; /* angular diameter at 1 AU and magnitude */ X double lsn, rsn; /* true geoc lng of sun, dist from sn to earth*/ X double el; /* elongation */ X double f; /* phase from earth */ X X lp->l_now = *np; X sunpos (mjd, &lsn, &rsn); X if (p == OBJX || p == OBJY) X obj_cir(mjd,p,&lpd0,&psi0,&rp0,&rho0,&lam,&bet,&sp->s_mag); X else { X double deps, dpsi; X double a; X plans(mjd, p, &lpd0, &psi0, &rp0, &rho0, &lam, &bet, &dia,&mag); X nutation (mjd, &deps, &dpsi); /* correct for nutation */ X lam += dpsi; X a = lsn-lam; /* and 20.4" aberation */ X lam -= degrad(20.4/3600)*cos(a)/cos(bet); X bet -= degrad(20.4/3600)*sin(a)*sin(bet); X } X X ecl_eq (mjd, bet, lam, &lp->l_ra, &lp->l_dec); X X sp->s_ra = lp->l_ra; X sp->s_dec = lp->l_dec; X if (epoch != EOD) X precess (mjd, epoch, &sp->s_ra, &sp->s_dec); X sp->s_edist = rho0; X sp->s_sdist = rp0; X elongation (lam, bet, lsn, &el); X el = raddeg(el); X sp->s_elong = el; X f = (rp0 > 0.0) X ? 0.25 * (((rp0+rho0)*(rp0+rho0) - rsn*rsn)/(rp0*rho0)) : 0.0; X sp->s_phase = f*100.0; /* percent */ X if (p != OBJX && p != OBJY) { X sp->s_size = dia/rho0; X sp->s_mag = mag + 5.0*log(rp0*rho0/sqrt(f))/log(10.0); X } X sp->s_hlong = lpd0; X sp->s_hlat = psi0; X new = 1; X } X X /* alt, az; correct for parallax and refraction; use eod ra/dec */ X now_lst (np, &lst); X ha = hrrad(lst) - lp->l_ra; X if (sp->s_edist > 0.0) { X ehp = (2.0*6378.0/146.0e6) / sp->s_edist; X ta_par (ha, lp->l_dec, lat, height, ehp, &ha, &dec); X } else X dec = lp->l_dec; X hadec_aa (lat, ha, dec, &alt, &az); X refract (pressure, temp, alt, &alt); X sp->s_alt = alt; X sp->s_az = az; X lp->l_sky = *sp; X return (new); X} X X/* find local times when sun is 18 degrees below horizon. X * return 0 if just returned same stuff as previous call, else 1 if new. X */ Xtwilight_cir (np, dawn, dusk, status) XNow *np; Xdouble *dawn, *dusk; Xint *status; X{ X static Now last_now = {NOMJD}; X static double last_dawn, last_dusk; X static int last_status; X int new; X X if (same_cir (np, &last_now) && same_lday (np, &last_now)) { X *dawn = last_dawn; X *dusk = last_dusk; X *status = last_status; X new = 0; X } else { X double x; X (void) riset_cir (SUN,np,0,TWILIGHT,dawn,dusk,&x,&x,&x,&x,status); X last_dawn = *dawn; X last_dusk = *dusk; X last_status = *status; X last_now = *np; X new = 1; X } X return (new); X} X X/* find sun's circumstances now. X * as is the desired accuracy, in arc seconds; use 0.0 for best possible. X * return 0 if only alt/az changes, else 1 if all other stuff updated too. X */ Xsun_cir (as, np, sp) Xdouble as; XNow *np; XSky *sp; X{ X static Sky last_sky; X static Now last_now = {NOMJD}; X static double last_ra, last_dec; /* unprecessed ra/dec */ X double lst, alt, az; X double ehp, ha, dec; /* ehp: angular dia of earth from body */ X int new; X X if (same_cir (np, &last_now) && about_now (np, &last_now, as*.00028)) { X *sp = last_sky; X new = 0; X } else { X double lsn, rsn; X double deps, dpsi; X X last_now = *np; X sunpos (mjd, &lsn, &rsn); /* sun's true ecliptic long X * and dist X */ X nutation (mjd, &deps, &dpsi); /* correct for nutation */ X lsn += dpsi; X lsn -= degrad(20.4/3600); /* and light travel time */ X X sp->s_edist = rsn; X sp->s_sdist = 0.0; X sp->s_elong = 0.0; X sp->s_size = raddeg(4.65242e-3/rsn)*3600*2; X sp->s_mag = -26.8; X sp->s_hlong = lsn-PI; /* geo- to helio- centric */ X range (&sp->s_hlong, 2*PI); X sp->s_hlat = 0.0; X X ecl_eq (mjd, 0.0, lsn, &last_ra, &last_dec); X sp->s_ra = last_ra; X sp->s_dec = last_dec; X if (epoch != EOD) X precess (mjd, epoch, &sp->s_ra, &sp->s_dec); X new = 1; X } X X now_lst (np, &lst); X ha = hrrad(lst) - last_ra; X ehp = (2.0 * 6378.0 / 146.0e6) / sp->s_edist; X ta_par (ha, last_dec, lat, height, ehp, &ha, &dec); X hadec_aa (lat, ha, dec, &alt, &az); X refract (pressure, temp, alt, &alt); X sp->s_alt = alt; X sp->s_az = az; X last_sky = *sp; X return (new); X} X X/* find moon's circumstances now. X * as is the desired accuracy, in arc seconds; use 0.0 for best possible. X * return 0 if only alt/az changes, else 1 if all other stuff updated too. X */ Xmoon_cir (as, np, sp) Xdouble as; XNow *np; XSky *sp; X{ X static Sky last_sky; X static Now last_now = {NOMJD}; X static double ehp; X static double last_ra, last_dec; /* unprecessed */ X double lst, alt, az; X double ha, dec; X int new; X X if (same_cir (np, &last_now) && about_now (np, &last_now, as*.000021)) { X *sp = last_sky; X new = 0; X } else { X double lam, bet; X double deps, dpsi; X double lsn, rsn; /* sun long in rads, earth-sun dist in au */ X double edistau; /* earth-moon dist, in au */ X double el; /* elongation, rads east */ X X last_now = *np; X moon (mjd, &lam, &bet, &ehp); /* moon's true ecliptic loc */ X nutation (mjd, &deps, &dpsi); /* correct for nutation */ X lam += dpsi; X range (&lam, 2*PI); X X sp->s_edist = 6378.14/sin(ehp); /* earth-moon dist, want km */ X sp->s_size = 3600*31.22512*sin(ehp);/* moon angular dia, seconds */ X sp->s_hlong = lam; /* save geo in helio fields */ X sp->s_hlat = bet; X X ecl_eq (mjd, bet, lam, &last_ra, &last_dec); X sp->s_ra = last_ra; X sp->s_dec = last_dec; X if (epoch != EOD) X precess (mjd, epoch, &sp->s_ra, &sp->s_dec); X X sunpos (mjd, &lsn, &rsn); X range (&lsn, 2*PI); X elongation (lam, bet, lsn, &el); X X /* solve triangle of earth, sun, and elongation for moon-sun dist */ X edistau = sp->s_edist/1.495979e8; /* km -> au */ X sp->s_sdist = X sqrt (edistau*edistau + rsn*rsn - 2.0*edistau*rsn*cos(el)); X X /* TODO: improve mag; this is based on a flat moon model. */ X sp->s_mag = -12.7 + 2.5*(log10(PI) - log10(PI/2*(1+1.e-6-cos(el)))); X X sp->s_elong = raddeg(el); /* want degrees */ X sp->s_phase = fabs(el)/PI*100.0; /* want non-negative % */ X new = 1; X } X X /* show topocentric alt/az by correcting ra/dec for parallax X * as well as refraction. X */ X now_lst (np, &lst); X ha = hrrad(lst) - last_ra; X ta_par (ha, last_dec, lat, height, ehp, &ha, &dec); X hadec_aa (lat, ha, dec, &alt, &az); X refract (pressure, temp, alt, &alt); X sp->s_alt = alt; X sp->s_az = az; X last_sky = *sp; X return (new); X} X X/* given geocentric ecliptic longitude and latitude, lam and bet, of some object X * and the longitude of the sun, lsn, find the elongation, el. this is the X * actual angular separation of the object from the sun, not just the difference X * in the longitude. the sign, however, IS set simply as a test on longitude X * such that el will be >0 for an evening object <0 for a morning object. X * to understand the test for el sign, draw a graph with lam going from 0-2*PI X * down the vertical axis, lsn going from 0-2*PI across the hor axis. then X * define the diagonal regions bounded by the lines lam=lsn+PI, lam=lsn and X * lam=lsn-PI. the "morning" regions are any values to the lower left of the X * first line and bounded within the second pair of lines. X * all angles in radians. X */ Xelongation (lam, bet, lsn, el) Xdouble lam, bet, lsn; Xdouble *el; X{ X *el = acos(cos(bet)*cos(lam-lsn)); X if (lam>lsn+PI || lam>lsn-PI && lam<lsn) *el = - *el; X} X X/* return whether the two Nows are for the same observing circumstances. */ Xsame_cir (n1, n2) Xregister Now *n1, *n2; X{ X return (n1->n_lat == n2->n_lat X && n1->n_lng == n2->n_lng X && n1->n_temp == n2->n_temp X && n1->n_pressure == n2->n_pressure X && n1->n_height == n2->n_height X && n1->n_tz == n2->n_tz X && n1->n_epoch == n2->n_epoch); X} X X/* return whether the two Nows are for the same LOCAL day */ Xsame_lday (n1, n2) XNow *n1, *n2; X{ X return (mjd_day(n1->n_mjd - n1->n_tz/24.0) == X mjd_day(n2->n_mjd - n2->n_tz/24.0)); X} X X/* return whether the mjd of the two Nows are within dt */ Xstatic Xabout_now (n1, n2, dt) XNow *n1, *n2; Xdouble dt; X{ X return (fabs (n1->n_mjd - n2->n_mjd) <= dt/2.0); X} X Xnow_lst (np, lst) XNow *np; Xdouble *lst; X{ X utc_gst (mjd_day(mjd), mjd_hr(mjd), lst); X *lst += radhr(lng); X range (lst, 24.0); X} X X/* round a time in days, *t, to the nearest second, IN PLACE. */ Xrnd_second (t) Xdouble *t; X{ X *t = floor(*t*SPD+0.5)/SPD; X} X Xdouble Xmjd_day(jd) Xdouble jd; X{ X return (floor(jd-0.5)+0.5); X} X Xdouble Xmjd_hr(jd) Xdouble jd; X{ X return ((jd-mjd_day(jd))*24.0); X} END_OF_FILE if test 10483 -ne `wc -c <'circum.c'`; then echo shar: \"'circum.c'\" unpacked with wrong size! fi # end of 'circum.c' fi if test -f 'ephem.db' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'ephem.db'\" else echo shar: Extracting \"'ephem.db'\" \(11652 characters\) sed "s/^X//" >'ephem.db' <<'END_OF_FILE' X* ephem database. X* X* these are sorted for easy reading but they don't have to be in any order. X* things will run faster if you put the objects you use nearer the top. X* X* elliptical format: X* i = inclination, degrees X* O = longitude of ascending node, degrees X* o = argument of perihelion, degrees X* a = mean distance (aka semi-major axis), AU X* n = daily motion, degrees per day X* e = eccentricity, X* M = mean anomaly (ie, degrees from perihelion), X* E = epoch date (ie, time of M), X* D = the equinox year (ie, time of i/O/o). X* g/k or H/G = magnitude model X* X* parabolic format: X* epoch of perihelion, X* inclination, degrees X* argument of perihelion, degrees X* perihelion distance, AU X* longitude of the ascending node, degrees X* reference epoch of the parameters, X* absolute magnitude, X* luminosity index X* X* fixed format: X* ra, hours X* dec, degrees X* magnitude X* reference epoch X X* from IAU circular 4985 XAustin,p,4/9.9715/1990,58.9574,61.5625,0.349854,75.2223,1950.0,4.5,4 X* from IAU circular 4986 XCernis,p,3/17.2967/1990,48.138,100.588,1.06849,347.727,1950,0,0 X* from IAU circular 4984 XGeorge,p,4/11.9396/1990,59.3652,137.8482,1.569001,279.3118,1950,0,0 X*Comet Levy (1990c) elements from IAUC 5060 (25 Jul 1990);g & k by J. Fedock XLevy,p,10/24.6277/1990,131.5951,242.6328,0.938779,138.6561,1950.0,4.2,3.4 X*Comet Tsuchiya-Kiuchi (1990i) from IAUC 5055 (19 Jul 1990);g & k by J. Fedock XTK,p,9/28.648/1990,143.758,180.830,1.09430,330.059,1950,5.5,4 X X*Comet Honda-Mrkos-Pajdusakova (1990f) elements from IAUC 5035 (19 June 1990) X*g & k via least squares fit by J. Fedock (10 Aug 90). XHMP,e,4.2224,88.7097,325.702,3.03891,0.186049,0.821936,0,9/12.6864/1990,1950,g14.018,7.946 X X* updated elements for Pluto XPluto,e,17.1519,110.2183,113.5202,39.37210,.00398953,0.24678,0.1782,10/1/1989,2000.0,g5.0,0.0 X XVesta,e,7.139,104.015,149.986,2.3607,0.27174,0.0906,152.190,11/5/1990,2000.0,3.16,0.34 XVesta89,e,7.139,104.015,150.175,2.3613,0.27163,0.0906,43.314,10/1/1989,2000.0,3.16,0.34 XCeres,e,10.607,80.702,71.274,2.7685,0.21396,0.0780,287.265,10/1/1989,2000.0,3.32,0.11 XHalley,e,162.238,58.154,111.857,17.9435,0.0129674,0.9673,0,1986.109,1950,3.66,7.05 XPallas,e,34.804,173.323,309.796,2.7703,0.21375,0.2347,273.779,10/1/1989,2000.0,4.13,0.15 XEunomia,e,11.76001,292.89583,97.40910,2.6446692,0.22916434,0.1850083,236.28800,8/27/1988,1950.0,5.22,0.20 XEunomia,e,11.765,293.619,97.591,2.6437,0.22929,0.1849,327.856,10/1/1989,2000.0,5.22,0.20 XJuno,e,12.991,170.542,246.787,2.6692,0.22601,0.2575,205.808,11/5/1990,2000.0,5.31,0.30 XJuno89,e,12.993,170.556,246.744,2.6682,0.22614,0.2580,115.411,10/1/1989,2000.0,5.31,0.30 XHygiea,e,3.840,283.833,315.832,3.1365,0.17743,0.1202,104.089,11/5/1990,2000.0,5.37,0.15 XIris,e,5.513,260.100,144.725,2.3864,0.26735,0.2292,239.261,11/5/1990,2000.0,5.56,0.25 XHebe,e,14.781,139.033,238.480,2.4250,0.26100,0.2020,253.786,11/5/1990,2000.0,5.70,0.24 XHerculina,e,16.35677,107.39552,75.08723,2.7711409,0.21365652,0.1763770,199.36894,10/1/1989,1950.0,5.78,0.22 XAmphitrite,e,6.110,356.625,63.020,2.5546,0.24139,0.0715,294.249,11/5/1990,2000.0,5.84,0.21 XDembowska,e,8.264,32.824,343.637,2.9246,0.19707,0.0901,257.577,11/5/1990,2000.0,5.98,0.32 XPsyche,e,3.089,150.508,227.697,2.9229,0.19723,0.1333,37.474,11/5/1990,2000.0,5.98,0.22 XPsyche89,e,3.089,150.508,227.581,2.9234,0.19718,0.1335,318.680,10/1/1989,2000.0,5.98,0.22 XInteramnia,e,17.301,281.072,92.206,3.0631,0.18385,0.1471,350.196,11/5/1990,2000.0,6.00,0.02 XLaetitia,e,10.368,157.417,208.197,2.7677,0.21405,0.1145,237.595,11/5/1990,2000.0,6.16,0.25 XDavida,e,15.937,107.998,339.207,3.1728,0.17439,0.1783,314.054,11/5/1990,2000.0,6.17,0.02 XIrene,e,9.113,86.863,95.016,2.5858,0.23703,0.1665,223.034,11/5/1990,2000.0,6.27,0.09 XIrene89,e,9.113,86.867,95.052,2.5867,0.23691,0.1661,128.194,10/1/1989,2000.0,6.27,0.09 XEuropa,e,7.439,129.275,337.304,3.1022,0.18038,0.1000,164.467,11/5/1990,2000.0,6.29,0.15 XElenora,e,18.429,140.729,5.535,2.7962,0.21079,0.1170,304.553,11/5/1990,2000.0,6.32,0.32 XMetis,e,5.585,69.112,5.315,2.3865,0.26733,0.1219,270.833,10/1/1989,2000.0,6.32,0.29 XMelpomene,e,10.137,150.705,227.396,2.2950,0.28349,0.2185,200.804,11/5/1990,2000.0,6.41,0.17 XFlora,e,5.888,111.120,284.896,2.2016,0.30171,0.1561,296.988,11/5/1990,2000.0,6.48,0.33 XKalliope,e,13.696,66.469,355.776,2.9112,0.19842,0.0977,291.742,11/5/1990,2000.0,6.49,0.22 X XSirius,f,6:45:9,-16:43,-1.4,2000 XCanopus,f,6:23:57,-52:41,-0.7,2000 XArcturus,f,14:15:40,19:11,-0.1,2000 XVega,f,18:36:56,38:47,0.04,2000 XCapella,f,5:16:41,46:0,0.06,2000 XRigel,f,5:14:32,-8:12,0.15,2000 XRigil,f,14:39:36,-60:50,0.33,2000 XProcyon,f,7:39:18,5:14,0.36,2000 XAchernar,f,1:37:42,-57:15,0.49,2000 XHadar,f,14:3:50,-60:22,0.61,2000 XAltair,f,19:50:47,8:52,0.75,2000 XBetelgeuse,f,5:55:10,7:24,0.8,2000 XAldebaran,f,4:35:55,16:30,0.86,2000 XSpica,f,13:25:11,-11:9,0.97,2000 XAntares,f,16:29:25,-26:26,1.08,2000 XPollux,f,7:45:19,28:1,1.15,2000 XFomalhaut,f,22:57:39,-29:37,1.15,2000 XDeneb,f,20:41:26,45:16,1.25,2000 XMimosa,f,12:47:44,-59:42,1.27,2000 XRegulus,f,10:8:22,11:58,1.35,2000 XAdara,f,6:58:38,-28:58,1.5,2000 XShaula,f,17:33:36,-37:6,1.62,2000 XBellatrix,f,5:25:8,6:21,1.63,2000 XAlnath,f,5:26:17,28:36,1.65,2000 XAlnilam,f,5:36:12,-1:12,1.69,2000 XDubhe,f,11:3:44,61:45,1.79,2000 XAlioth,f,12:54:2,55:57,1.79,2000 XMirfak,f,3:24:20,49:51,1.8,2000 XKaus,f,18:24:10,-34:23,1.83,2000 XBenetnasch,f,13:47:32,49:19,1.88,2000 XMenkalinan,f,5:59:32,44:57,1.9,2000 XMirzam,f,6:22:42,-17:57,1.98,2000 XMira,f,2:19:21,-2:59,2,2000 XHamal,f,2:7:10,23:27,2.01,2000 XDiphda,f,0:43:35,-17:59,2.03,2000 XPolaris,f,2:31:13,89:15,2.04,2000 XMirach,f,1:9:44,35:37,2.06,2000 XAlpheratz,f,0:8:23,29:5,2.07,2000 XRas,f,17:34:56,12:34,2.07,2000 XKocab,f,14:50:43,74:9,2.07,2000 XDenebola,f,11:49:4,14:34,2.13,2000 XAlgol,f,3:8:11,40:57,2.15,2000 XMintaka,f,5:32:1,0:18,2.2,2000 XSchedar,f,0:40:31,56:32,2.22,2000 XRastaban,f,17:56:36,51:29,2.23,2000 XAlphecca,f,15:34:41,26:43,2.23,2000 XMizar,f,13:23:56,54:56,2.27,2000 XCaph,f,0:9:10,59:9,2.27,2000 XMerak,f,11:1:51,56:23,2.38,2000 XPulcherrima,f,14:44:59,27:5,2.4,2000 XEniph,f,21:44:11,9:53,2.4,2000 XPhecda,f,11:53:49,53:42,2.43,2000 XAlderamin,f,21:18:35,62:35,2.44,2000 XMarkab,f,23:4:46,15:12,2.5,2000 XMekab,f,3:2:17,4:6,2.52,2000 XZozca,,f,11:14:6,20:31,2.56,2000 XArneb,f,5:32:44,-17:50,2.58,2000 XZuben,f,15:17:0,-9:23,2.61,2000 XPhakt,f,5:39:39,-34:5,2.63,2000 XSheratan,f,1:54:39,20:48,2.63,2000 XUnukalhay,f,15:44:17,6:25,2.65,2000 XMuphrid,f,13:54:41,18:24,2.68,2000 XTarazed,f,19:46:15,10:37,2.72,2000 XIB,f,14:50:53,-16:3,2.75,2000 XCursa,f,5:7:51,-5:5,2.77,2000 XKelb,f,17:43:28,4:34,2.77,2000 XKornephoros,f,16:30:13,21:29,2.78,2000 XAlwaid,f,17:30:26,52:19,2.79,2000 XAlgenib,f,0:13:14,15:11,2.83,2000 XVindemiatrix,f,13:2:11,10:58,2.83,2000 XAlcyone,f,3:47:29,24:7,2.87,2000 XSadalsud,f,21:31:34,-5:35,2.88,2000 XGomeisa,f,7:27:9,8:17,2.89,2000 XSadalmelik,f,22:5:47,0:19,2.93,2000 XZaurak,f,3:58:2,-13:31,2.95,2000 XMEbsuta,f,6:43:56,25:8,2.99,2000 XAlbireo,f,19:30:43,27:58,3.08,2000 XTalitha,f,8:59:13,48:2,3.15,2000 XAlphirk,f,21:28:39,70:33,3.18,2000 XAlrai,f,23:39:20,77:37,3.22,2000 XSulaphat,f,18:58:56,32:41,3.25,2000 XSkat,f,22:54:39,-15:49,3.27,2000 XMegrez,f,12:15:26,57:2,3.31,2000 XHomam,f,22:41:27,10:50,3.39,2000 XSheliak,f,18:50:4,33:22,3.43,2000 XNekkar,f,15:1:57,40:23,3.49,2000 XWasat,f,7:20:7,21:59,3.53,2000 XRotanev,f,20:37:33,14:36,3.58,2000 XZawijah,f,11:50:42,1:46,3.61,2000 XThuban,f,14:4:24,64:22,3.65,2000 XBaten,f,1:51:27,-10:20,3.72,2000 XSvalocin,f,20:39:39,15:55,3.77,2000 XSadachbia,f,22:21:39,-1:23,3.84,2000 XZuben,f,15:35:32,-14:47,3.9,2000 XAlbireo,f,19:30:45,27:58,5.11,2000 XM1,f,5:34:30,22:2,8.4,2000 XM2,f,21:33:17,0:47,6.3,2000 XM3,f,13:42:9,28:21,6.4,2000 XM4,f,16:23:18,-26:30,6.4,2000 XM5,f,15:19:16,2:5,6.2,2000 XM6,f,17:39:38,-32:13,5.3,2000 XM7,f,17:53:40,-34:48,3.2,2000 XM8,f,18:3:32,-24:23,6,2000 XM9,f,17:18:28,-18:31,7.3,2000 XM10,f,16:57:19,-4:7,6.7,2000 XM11,f,18:51:21,-6:16,6.3,2000 XM12,f,16:47:18,-1:58,6.6,2000 XM13,f,16:41:54,36:27,5.7,2000 XM14,f,17:37:19,-3:15,7.7,2000 XM15,f,21:30:13,12:12,6,2000 XM16,f,18:19:25,-13:47,6.5,2000 XM17,f,18:21:27,-16:11,7,2000 XM18,f,18:19:27,-17:8,7.5,2000 XM19,f,17:2:33,-26:15,6.6,2000 XM20,f,18:2:31,-23:2,9,2000 XM21,f,18:4:31,-22:30,6.5,2000 XM22,f,18:36:32,-23:55,5.9,2000 XM23,f,17:56:29,-19:1,6.9,2000 XM24,f,18:18:28,-18:24,4.6,2000 XM25,f,18:32:29,-19:15,6,2000 XM26,f,18:45:22,-9:24,9.3,2000 XM27,f,20:0:5,22:44,7.6,2000 XM28,f,18:24:33,-24:52,7.3,2000 XM29,f,20:23:55,38:32,7.1,2000 XM30,f,21:40:25,-23:8,8.4,2000 XM31,f,0:43:22,41:17,4.8,2000 XM32,f,0:43:22,40:53,8.7,2000 XM33,f,1:34:25,30:41,6.7,2000 XM34,f,2:42:37,42:49,5.5,2000 XM35,f,6:9:32,24:21,5.3,2000 XM36,f,5:36:40,34:6,6.3,2000 XM37,f,5:53:38,32:33,6.2,2000 XM38,f,5:28:41,35:49,7.4,2000 XM39,f,21:32:54,48:28,5.2,2000 XM40,f,12:35:19,58:13,9,2000 XM41,f,6:47:3,-20:44,5,2000 XM42,f,5:35:14,-5:23,5,2000 XM43,f,5:35:14,-5:16,7,2000 XM44,f,8:40:26,19:59,3.7,2000 XM45,f,3:47:29,24:8,1.4,2000 XM46,f,7:42:9,-14:50,6,2000 XM47,f,7:37:9,-14:30,4.5,2000 XM48,f,8:13:14,-5:46,5.3,2000 XM49,f,12:30:16,7:59,8.6,2000 XM50,f,7:3:12,-8:20,6.9,2000 XM51,f,13:30:3,47:10,8.1,2000 XM52,f,23:24:7,61:37,7.3,2000 XM53,f,13:13:14,18:9,7.6,2000 XM54,f,18:54:36,-30:29,8.7,2000 XM55,f,19:39:35,-30:57,7.1,2000 XM56,f,19:16:58,30:11,8.2,2000 XM57,f,18:53:56,33:3,9.3,2000 XM58,f,12:38:16,11:48,9.2,2000 XM59,f,12:42:16,11:39,9.6,2000 XM60,f,12:44:16,11:33,9.7,2000 XM61,f,12:22:17,4:28,9.99,2000 XM62,f,17:1:36,-30:7,6.6,2000 XM63,f,13:16:7,42:0,9.5,2000 XM64,f,12:57:14,21:40,8.8,2000 XM65,f,11:19:18,13:5,9.3,2000 XM66,f,11:20:18,12:59,8.4,2000 XM67,f,8:50:22,11:48,6.1,2000 XM68,f,12:39:20,-26:45,8.2,2000 XM69,f,18:30:38,-32:21,8.9,2000 XM70,f,18:42:38,-32:19,9.6,2000 XM71,f,19:54:7,18:47,9,2000 XM72,f,20:53:22,-12:33,9.8,2000 XM73,f,20:57:22,-12:43,9.99,2000 XM74,f,1:37:21,15:49,9.99,2000 XM75,f,20:5:29,-21:57,8,2000 XM76,f,1:42:35,51:36,9.99,2000 XM77,f,2:43:17,0:2,8.9,2000 XM78,f,5:47:17,0:3,8,2000 XM79,f,5:24:2,-24:32,8.4,2000 XM80,f,16:17:30,-22:59,7.7,2000 XM81,f,9:56:3,69:2,7.9,2000 XM82,f,9:56:5,69:40,8.8,2000 XM83,f,13:37:25,-29:54,9.99,2000 XM84,f,12:25:16,12:52,9.3,2000 XM85,f,12:25:16,18:10,9.3,2000 XM86,f,12:26:16,12:55,9.7,2000 XM87,f,12:31:16,12:22,9.2,2000 XM88,f,12:32:16,14:24,9.99,2000 XM89,f,12:36:16,12:32,9.5,2000 XM90,f,12:37:16,13:8,9.97,2000 XM91,f,12:36:16,13:54,9.99,2000 XM92,f,17:17:46,43:8,6.1,2000 XM93,f,7:44:4,-23:52,6,2000 XM94,f,12:51:11,41:6,7.9,2000 XM95,f,10:43:19,11:44,9.99,2000 XM96,f,10:47:19,11:48,9.1,2000 XM97,f,11:15:27,54:59,9.99,2000 XM98,f,12:14:16,14:53,9.99,2000 XM99,f,12:19:16,14:24,9.99,2000 XM100,f,12:23:16,15:48,9.99,2000 XM101,f,14:2:53,54:20,9.6,2000 XM102,f,15:6:27,55:45,9.99,2000 XM103,f,1:33:40,60:43,7.4,2000 XM104,f,12:40:18,-11:37,8.7,2000 XM105,f,10:48:19,12:34,9.2,2000 XM106,f,12:19:14,47:17,8.6,2000 XM107,f,16:32:24,-13:5,9.2,2000 XM108,f,11:12:27,55:39,9.9,2000 XM109,f,11:58:18,53:21,9.9,2000 Xm110,f,0:40:22,41:43,9.4,2000 XUCNGC104,f,0:24:8,-72:5,5,2000 XNGC225,f,0:43:32,61:48,6.5,2000 XNGC362,f,1:2:25,-70:50,6,2000 XNGC457,f,1:19:10,58:19,6.5,2000 XNGC663,f,1:45:57,61:15,6.5,2000 XNGCGC869,f,2:20:45,57:9,5.2,2000 XNGC2070,f,5:38:44,-69:7,5.7,2000 XNGC2244,f,6:32:40,4:52,5.7,2000 XNGC2440,f,7:41:50,-18:12,7,2000 XNGC2506,f,7:59:54,-10:35,7.5,2000 XNGC2808,f,9:11:59,-64:51,7,2000 XNGC3242,f,10:24:43,-18:38,7,2000 XNGC3532,f,11:6:26,-58:40,7,2000 XNGC3766,f,11:36:14,-61:37,6.5,2000 XNGC4258,f,12:18:59,47:17,7.5,2000 XNGC4565,f,12:36:24,25:59,7,2000 XNGC5322,f,13:49:35,60:10,6,2000 XNGC6025,f,16:3:41,-60:29,6,2000 XNGC6067,f,16:13:21,-54:13,7,2000 XNGC6210,f,16:44:28,25:28,7,2000 XNGC6543,f,17:58:35,66:38,6.5,2000 XNGC6572,f,18:12:38,6:51,8,2000 XNGC6752,f,19:10:50,-59:59,7,2000 XNGC7009,f,21:4:8,-11:22,7,2000 XNGC7243,f,22:15:5,49:53,6.5,2000 XNGC7662,f,23:25:49,42:29,7,2000 XNGC7772,f,23:51:33,16:16,5,2000 XNGC7789,f,23:57:2,56:43,8,2000 END_OF_FILE if test 11652 -ne `wc -c <'ephem.db'`; then echo shar: \"'ephem.db'\" unpacked with wrong size! fi # end of 'ephem.db' fi if test -f 'plot.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'plot.c'\" else echo shar: Extracting \"'plot.c'\" \(11261 characters\) sed "s/^X//" >'plot.c' <<'END_OF_FILE' X/* code to support the plotting capabilities. X * idea is to let the operator name a plot file and mark some fields for X * logging. then after each screen update, the logged fields are written to X * the plot file. later, the file may be plotted (very simplistically by X * ephem, for now anyway, or by some other program entirely.). X * X * format of the plot file is one line per coordinate: label,x,y X * if z was specified, it is a fourth field. X * x,y,z are plotted using %g format. X */ X X#include <stdio.h> X#include <math.h> X#include "screen.h" X Xextern char *strcpy(); Xextern errno; Xextern char *sys_errlist[]; X#define errsys (sys_errlist[errno]) X X#define TRACE(x) {FILE *fp = fopen("trace","a"); fprintf x; fclose(fp);} X X#define MAXPLTLINES 10 /* max number of labeled lines we can track. X * note we can't store more than NFLOGS fields X * anyway (see flog.c). X */ X#define FNLEN (14+1) /* longest filename; plus 1 for \0 */ X Xstatic char plt_filename[FNLEN] = "ephem.plt"; /* default plot file name */ Xstatic FILE *plt_fp; /* the plot file; == 0 means don't plot */ X X/* store the label and rcfpack()s for each line to track. */ Xtypedef struct { X char pl_label; X int pl_rcpx, pl_rcpy, pl_rcpz; X} PltLine; Xstatic PltLine pltlines[MAXPLTLINES]; Xstatic int npltlines; /* number of pltlines[] in actual use */ X Xstatic int plt_in_polar; /*if true plot in polar coords, else cartesian*/ Xstatic int pltsrchfld; /* set when the Search field is to be plotted */ X X/* picked the Plot label: X * if on, just turn it off. X * if off, turn on, define fields or select name of file to plot and do it. X * TODO: more flexibility, more relevance. X */ Xplot_setup() X{ X if (plt_fp) X plt_turn_off(); X else { X static char *chcs[4] = { X "Select fields", "Display a plot file", (char *)0, X "Begin plotting" X }; X static int fn; /* start with 0, then remember for next time */ X ask: X chcs[2] = plt_in_polar ? "Polar coords" : "Cartesian coords"; X switch (popup(chcs, fn, npltlines > 0 ? 4 : 3)) { X case 0: fn = 0; plt_select_fields(); goto ask; X case 1: fn = 1; plt_file(); goto ask; X case 2: fn = 2; plt_in_polar ^= 1; goto ask; X case 3: fn = 3; plt_turn_on(); break; X default: break; X } X } X} X X/* write the active plotfields to the current plot file, if one is open. */ Xplot() X{ X if (plt_fp) { X PltLine *plp; X double x, y, z; X if (!srch_ison() && pltsrchfld) { X /* if searching is not on but we are plotting the search X * funtion we must evaluate and log it ourselves here and now. X * plt_turn_on() insured there is a good function to eval. X * N.B. if searching IS on, we rely on main() having called X * srch_eval() BEFORE plot() so it is already evaluated. X */ X double e; X char errmsg[128]; X if (execute_expr (&e, errmsg) < 0) { X f_msg (errmsg); X plt_turn_off(); X return; X } else X (void) flog_log (R_SRCH, C_SRCH, e, ""); X } X /* plot in order of original selection */ X for (plp = pltlines; plp < &pltlines[npltlines]; plp++) { X if (flog_get (plp->pl_rcpx, &x, (char *)0) == 0 X && flog_get (plp->pl_rcpy, &y, (char *)0) == 0) { X (void) fprintf (plt_fp, "%c,%.12g,%.12g", plp->pl_label, X x, y); X if (flog_get (plp->pl_rcpz, &z, (char *)0) == 0) X (void) fprintf (plt_fp, ",%.12g", z); X (void) fprintf (plt_fp, "\n"); X } X } X } X} X Xplot_prstate (force) Xint force; X{ X static last; X int this = plt_fp != 0; X X if (force || this != last) { X f_string (R_PLOT, C_PLOTV, this ? " on" : "off"); X last = this; X } X} X Xplot_ison() X{ X return (plt_fp != 0); X} X Xstatic Xplt_reset() X{ X PltLine *plp; X X for (plp = &pltlines[npltlines]; --plp >= pltlines; ) { X (void) flog_delete (plp->pl_rcpx); X (void) flog_delete (plp->pl_rcpy); X (void) flog_delete (plp->pl_rcpz); X plp->pl_rcpx = plp->pl_rcpy = plp->pl_rcpz = 0; X } X npltlines = 0; X pltsrchfld = 0; X} X X/* let operator select the fields he wants to plot. X * register them with flog and keep rcfpack() in pltlines[] array. X * as a special case, set pltsrchfld if Search field is selected. X */ Xstatic Xplt_select_fields() X{ X static char hlp[] = "move and RETURN to select a field, or q to quit"; X static char sry[] = "Sorry; can not log any more fields."; X int r = R_UT, c = C_UTV; /* TODO: start where main was? */ X int sf = rcfpack (R_SRCH, C_SRCH, 0); X char buf[64]; X int rcp; X int i; X X plt_reset(); X for (i = 0; i < MAXPLTLINES; i++) { X (void) sprintf (buf, "select x field for line %d", i+1); X rcp = sel_fld (r, c, alt_menumask()|F_PLT, buf, hlp); X if (!rcp) X break; X if (flog_add (rcp) < 0) { X f_msg (sry); X break; X } X pltlines[i].pl_rcpx = rcp; X if (rcp == sf) X pltsrchfld = 1; X X (void) sprintf (buf, "select y field for line %d", i+1); X r = unpackr (rcp); c = unpackc (rcp); X rcp = sel_fld (r, c, alt_menumask()|F_PLT, buf, hlp); X if (!rcp) { X (void) flog_delete (pltlines[i].pl_rcpx); X break; X } X if (flog_add (rcp) < 0) { X (void) flog_delete (pltlines[i].pl_rcpx); X f_msg (sry); X break; X } X pltlines[i].pl_rcpy = rcp; X if (rcp == sf) X pltsrchfld = 1; X X (void) sprintf (buf, "select z field for line %d", i+1); X r = unpackr (rcp); c = unpackc (rcp); X rcp = sel_fld (r, c, alt_menumask()|F_PLT, buf, hlp); X if (rcp) { X if (flog_add (rcp) < 0) { X (void) flog_delete (pltlines[i].pl_rcpx); X (void) flog_delete (pltlines[i].pl_rcpy); X f_msg (sry); X break; X } X pltlines[i].pl_rcpz = rcp; X if (rcp == sf) X pltsrchfld = 1; X r = unpackr (rcp); c = unpackc (rcp); X } X X do { X (void) sprintf(buf,"enter a one-character label for line %d: ", X i+1); X f_prompt (buf); X } while (read_line (buf, 1) != 1); X pltlines[i].pl_label = *buf; X } X npltlines = i; X} X Xstatic Xplt_turn_off () X{ X (void) fclose (plt_fp); X plt_fp = 0; X plot_prstate(0); X} X X/* turn on plotting. X * establish a file to use (and thereby set plt_fp, the plotting_is_on flag). X * also check that there is a srch function if it is being plotted. X */ Xstatic Xplt_turn_on () X{ X int sf = rcfpack(R_SRCH, C_SRCH, 0); X char fn[FNLEN], fnq[NC]; X char *optype; X int n; X PltLine *plp; X X /* insure there is a valid srch function if we are to plot it */ X for (plp = &pltlines[npltlines]; --plp >= pltlines; ) X if ((plp->pl_rcpx == sf || plp->pl_rcpy == sf || plp->pl_rcpz == sf) X && !prog_isgood()) { X f_msg ("Plotting search function but it is not defined."); X return; X } X X /* prompt for file name, giving current as default */ X (void) sprintf (fnq, "file to write <%s>: ", plt_filename); X f_prompt (fnq); X n = read_line (fn, sizeof(fn)-1); X X /* leave plotting off if type END. X * reuse same fn if just type \n X */ X if (n < 0) X return; X if (n > 0) X (void) strcpy (plt_filename, fn); X X /* give option to append if file already exists */ X optype = "w"; X if (access (plt_filename, 2) == 0) { X while (1) { X f_prompt ("files exists; append or overwrite (a/o)?: "); X n = read_char(); X if (n == 'a') { X optype = "a"; X break; X } X if (n == 'o') X break; X } X } X X /* plotting is on if file opens ok */ X plt_fp = fopen (plt_filename, optype); X if (!plt_fp) { X char buf[NC]; X (void) sprintf (buf, "can not open %s: %s", plt_filename, errsys); X f_prompt (buf); X (void)read_char(); X } else { X /* add a title if desired */ X static char tp[] = "Title (q to skip): "; X f_prompt (tp); X if (read_line (fnq, PW - sizeof(tp)) > 0) X (void) fprintf (plt_fp, "* %s\n", fnq); X } X plot_prstate (0); X} X X/* ask operator for a file to plot. if it's ok, do it. X */ Xstatic Xplt_file () X{ X char fn[FNLEN], fnq[64]; X FILE *pfp; X int n; X X /* prompt for file name, giving current as default */ X (void) sprintf (fnq, "file to read <%s>: ", plt_filename); X f_prompt (fnq); X n = read_line (fn, sizeof(fn)-1); X X /* forget it if type END. X * reuse same fn if just type \n X */ X if (n < 0) X return; X if (n > 0) X (void) strcpy (plt_filename, fn); X X /* do the plot if file opens ok */ X pfp = fopen (plt_filename, "r"); X if (pfp) { X if (plt_in_polar) X plot_polar (pfp); X else X plot_cartesian (pfp); X (void) fclose (pfp); X } else { X char buf[NC]; X (void) sprintf (buf, "can not open %s: %s", plt_filename, errsys); X f_prompt (buf); X (void)read_char(); X } X} X X/* plot the given file on the screen in cartesian coords. X * TODO: add z tags somehow X * N.B. do whatever you like but redraw the screen when done. X */ Xstatic Xplot_cartesian (pfp) XFILE *pfp; X{ X static char fmt[] = "%c,%lf,%lf"; X double x, y; /* N.B. be sure these match what scanf's %lf wants*/ X double minx, maxx, miny, maxy; X char buf[128]; X int npts = 0; X char c; X X /* find ranges and number of points */ X while (fgets (buf, sizeof(buf), pfp)) { X if (sscanf (buf, fmt, &c, &x, &y) != 3) X continue; X if (npts++ == 0) { X maxx = minx = x; X maxy = miny = y; X } else { X if (x > maxx) maxx = x; X else if (x < minx) minx = x; X if (y > maxy) maxy = y; X else if (y < miny) miny = y; X } X } X X#define SMALL (1e-10) X if (npts < 2 || fabs(minx-maxx) < SMALL || fabs(miny-maxy) < SMALL) X f_prompt ("At least two different points required to plot."); X else { X /* read file again, this time plotting */ X rewind (pfp); X c_erase(); X while (fgets (buf, sizeof(buf), pfp)) { X int row, col; X if (sscanf (buf, fmt, &c, &x, &y) != 3) X continue; X row = NR-(int)((NR-1)*(y-miny)/(maxy-miny)+0.5); X col = 1+(int)((NC-1)*(x-minx)/(maxx-minx)+0.5); X if (row == NR && col == NC) X col--; /* avoid lower right scrolling corner */ X f_char (row, col, c); X } X X /* label axes */ X f_double (1, 1, "%g", maxy); X f_double (NR-1, 1, "%g", miny); X f_double (NR, 1, "%g", minx); X f_double (NR, NC-10, "%g", maxx); X } X X /* hit any key to resume... */ X (void) read_char(); X redraw_screen (2); /* full redraw */ X} X X/* plot the given file on the screen in polar coords. X * first numberic field in plot file is r, second is theta in degrees. X * TODO: add z tags somehow X * N.B. do whatever you like but redraw the screen when done. X */ Xstatic Xplot_polar (pfp) XFILE *pfp; X{ X static char fmt[] = "%c,%lf,%lf"; X double r, th; /* N.B. be sure these match what scanf's %lf wants*/ X double maxr; X char buf[128]; X int npts = 0; X char c; X X /* find ranges and number of points */ X while (fgets (buf, sizeof(buf), pfp)) { X if (sscanf (buf, fmt, &c, &r, &th) != 3) X continue; X if (npts++ == 0) X maxr = r; X else X if (r > maxr) X maxr = r; X } X X if (npts < 2) X f_prompt ("At least two points required to plot."); X else { X /* read file again, this time plotting */ X rewind (pfp); X c_erase(); X while (fgets (buf, sizeof(buf), pfp)) { X int row, col; X double x, y; X if (sscanf (buf, fmt, &c, &r, &th) != 3) X continue; X x = r * cos(th/57.2958); /* degs to rads */ X y = r * sin(th/57.2958); X row = NR-(int)((NR-1)*(y+maxr)/(2.0*maxr)+0.5); X col = 1+(int)((NC-1)*(x+maxr)/(2.0*maxr)/ASPECT+0.5); X if (row == NR && col == NC) X col--; /* avoid lower right scrolling corner */ X f_char (row, col, c); X } X X /* label radius */ X f_double (NR/2, NC-10, "%g", maxr); X } X X /* hit any key to resume... */ X (void) read_char(); X redraw_screen (2); /* full redraw */ X} END_OF_FILE if test 11261 -ne `wc -c <'plot.c'`; then echo shar: \"'plot.c'\" unpacked with wrong size! fi # end of 'plot.c' fi if test -f 'version.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'version.c'\" else echo shar: Extracting \"'version.c'\" \(9448 characters\) sed "s/^X//" >'version.c' <<'END_OF_FILE' X/* N.B. please increment version and date and note each change. */ X X#include "screen.h" X Xstatic char vmsg[] = "Version 4.21 August 23, 1990"; X X/* X * 4.21 8/23/90 fix dawn/dusk near vernal equinox. X * 4.20 8/15/90 add g/k and H/G magnitude model options for elliptical objects. X * 8/17 put moon's geocentric long/lat under Hlong/Hlat columns. X * allow entering negative decimal years. X * 8/20 init all static mjd storage to unlike times. X * 8/21 add USE_TERMIO option to io.c. X * 4.19 8/7/90 add listing feature, with 'L' hot-key. X * add title for plot file (as well as listing file). X * add some (void) casts for lint sake. X * 4.18 8/2/90 fix parabolic comet bug in objx.c (bad lam computation). X * 4.17 7/2/90 add 'c' short cut to Menu field. X * display full Dec precision for fixed objx setup. X * increase pluto auscale in watch.c, and guard screen boundries. X * add Pause feature. X * 7/27 further improve rise/set and dawn/dusk times. X * add MENU={DATA,RISET,SEP} config/arg option. X * 4.16 5/30/90 watch popup now allows changing formats without returning. X * add 'w' short cut to watch field. X * improve labeling a bit in Dome display. X * 4.15 5/2/90 move setjmp() in main so it catches fp errs from ephem.cfg too. X * 5/15 maintain name of objx/y. X * clean up objx.c. X * 5/16 fix bug circum.c related to phase of fixed objects. X * 5/22 add "Sky dome" watch display format (idea from Jeffery Cook). X * 5/23 remember last selection in watch, search, and plot popup menus. X * cleanup layout and add labels in the watch screens. X * 4.14 4/9/90 add y to body_tags[] in watch.c. X * 4/10 add ! support (#ifdef BANG in sel_fld()). X * 4/17 add #ifdef VMS and allow for no time zones (Karsten Spang). X * 4/23 switch to EPHEMCFG (no more HOME). X * add #include <stdlib.h> #ifdef VMS wherever atof() is used. X * 4/24 fix phase so it works for objects out of the ecliptic. X * 4.13 3/9/90 add support for second user-def object: "object y" X * fix bug updating obj ref epoch (always used PARABOLIC's) X * fix Turbo C workaround that prevented plotting sun dist. X * 3/13 fix bug preventing searching on separation column for objx X * 3/22 revamp elliptical object definition parameters to match AA. X * permit exiting/redrawing properly from within a popup too. X * add a bit more precision to plot labels. X * let plot files have comments too, ie, leading *'s X * 3/23 add "Lookup" to search config file for objects. X * 3/30 separate database from config file; add -d and EPHEMDB env var. X * catch SIGFPE and longjmp() back into main interation loop. X * 4/3 add magnitude to fixed-object database fields. X * 4.12 1/12/90 lay framework for orbital element support for object x. X * 1/15 fix slight bug related to nutation. X * plot fields in the same order they were selected. X * 1/18 add copywrite notice in main.c. X * note <sys/time.h> in time.c for BSD 4.3. X * 1/20 work on fixed and parabolic orbital elements. X * 1/25 work on elliptical orbital elements. X * 2/1 work on objx's magnitude models. X * add confirmation question before quitting. X * 2/6 add d,o,z special speed move chars. X * 2/8 watch: add LST to night sky and maintain RTC time back in main. X * 2/12 fix bug in timezone related to daytime flag. X * add w (week) watch advance key code. X * add cautionary note about no string[s].h to Readme X * 2/15 allow for precession moving dec outside range -90..90. X * 2/19 fix bug that wiggled cursor during plotting in rise/set menu. X * 2/20 fix bug preventing DAWN/DUSK/LON from being used in search func. X * 4.11 12/29 add PC_GRAPHICS option in mainmenu.c (no effect on unix version) X * 1/3/90 fix twilight error when sun never gets as low as -18 degs. X * 1/4/90 always find alt/az from eod ra/dec, not from precessed values. X * 1/9/90 lastmjd in plans.c was an int: prevented needless recalcs. X * 4.10 12/6/89 fix transit times of circumpolar objects that don't rise. X * fix plotting search function when searching is not on. X * 12/12 fix Objx rise/set bug. X * 12/21 don't erase last watch positions until computed all new ones. X * 12/23 added USE_BIOSCALLS to io.c: Doug McDonald's BIOS calls X * 12/27 allow dates to be entered as decimal years (for help with plots) X * 12/27 remove literal ESC chars in strings in io.c. X * 4.9 11/28/89 provide two forms of non-blocking reads for unix in io.c X * 11/30/89 take out superfluous ESC testing in chk_arrow(). X * guard better against bogus chars in sel_fld(). X * use %lf in scanf's. X * command-line arg PROPTS+ adds to settings from config file. X * change (int) casts in moduloes to (long) for 16bit int systems. X * 4.8 10/28/89 use doubles everywhere X * 10/31/89 add direct planet row selection codes. X * 11/2/89 improve compiler's fieldname parser. X * 11/3/89 switch from ESC to q for "go on" (CBREAK ESC not very portable) X * 11/6/89 allow plotting the search function too. X * 11/8/89 suppress screen updates while plotting and nstep > 1. X * 11/9/89 fix bug prohibiting plotting venus' sdist and objx's transit. X * 11/9/89 add option to plot in polar coords. X * 11/12/89 fix bug related to updating timezone name when it is changed. X * 11/21/89 fix bug in when to print info about object-x X * 11/21/89 increase MAXPLTLINES to 10 (to ease plotting all planet seps) X * 11/22/89 allow setting fields from command line too. X * 4.7 10/13/89 start adding general searching feature. start with flogging. X * 10/17/89 add compiler, first menu ideas, get binary srch working. X * 10/18/89 add parabolic-extrema and secant-0 solvers. X * 10/23/89 finish up new idea of one-line control and set-up "popup" menus. X * 4.6 10/29/89 improve transit circumstances by iterating as with rise/set. X * allow changing lst. X * show Updating message at better times. X * avoid overstrikes while watching and add trails option. X * allow for Turbo-C 2.0 printf bug using %?.0f". X * 4.5 9/24/89 add third table of all mutual planet angular distances. X * 4.4 9/21/89 add second planet table with rise/set times. X * all rise/set times may now use standard or adaptive horizons. X * 4.3 9/6/89 NM/FM calendar overstikes now use local time (was ut). X * display elongation of object x. X * better handling of typo when asking for refraction model. X * 4.2 7/24/89 specify 7 digits to plot file (not just default to 6) X * 4.1 7/18/89 use buffered output and fflush in read_char(). X * 4.0 7/8/89 add simple sky and solarsystem plotting (and rearrange fields) X * change mars' .cfg mnemonic from a to m. X * clean up nstep/NEW CIR handling X * quit adding our own .cfg suffixes, but... X * add looking for $HOME/.ephemrc (Ronald Florence) X * drop -b X * no longer support SITE X * 3.17 6/15/89 misspelt temperature prompt; sun -/= bug. (Mike McCants) X * change sun() to sunpos() for sake of Sun Microsystems. X * 3.16 6/9/89 allow JD to be set and plotted. X * c_clear (LATTIC_C) should use J not j (Alex Pruss) X * support SIGINT (Ronald Florence) X * 3.15 6/8/89 forget SIMPLETZ: now TZA and TZB. X * 3.14 6/6/89 add back borders but allow turning off via -b X * 3.13 5/26/89 fix Day/Nite picking loc bug. X * 3.12 5/25/89 add SIMPLETZ option to time.c for systems w/o tzset() X * files; couldn't plot dayln or niteln. X * 3.11 5/16/89 local time prompt said utc; add NiteLn; check for bad plot X * 3.10 4/27/89 allow caps for moving cursor around too X * 3.9 4/5/89 discard leading termcap delay digits, for now X * 3.8 3/2/89 shorten displayed precision, add heliocentric lat/long X * 3.7 2/13/89 change to ^d to quit program. X * 3.6 2/7/89 try adding .cfg suffix if can't find config file X * 3.5 2/2/89 sunrise/set times based on actual sun size and pressure/temp X * 3.4 1/22/89 calendar and all rise/set times based on local date, not utc X * 3.3 1/6/89 add z to plot files (still don't plot it however) X * 3.2 1/3/89 if set date/time then time does not inc first step X * 3.1 1/1/89 user def. graph labels; nstep/stpsz control; genuine c_eol X * 3.0 12/31/88 add graphing; add version to credits. X * 2.7 12/30/88 add version to credits. X * 2.6 12/28/88 twilight defined as 18 rather than 15 degrees below horizon X * 2.5 12/26/88 remove trace capability; add screen shadowing: ^l. X * 2.4 10/31/88 add credits banner, -s turns it off; savings time fix. X * 2.3 9/23/88 exchange Altitude/Elevation titles (no code changes) X * 2.2 9/20/88 more caution in aaha_aux() guarding acos() arg range X * 2.1 9/14/88 moon phase always >= 0 to match planets convention X * 2.0 9/13/88 add version ^v option X */ X Xversion() X{ X f_msg (vmsg); X} X Xstatic char *cre[] = { X"Ephem - an interactive astronomical ephemeris program", Xvmsg, X"", X"Copyright (c) 1990 by Elwood Charles Downey", X"", X"Permission is granted to make and distribute copies of this program", X"free of charge, provided the copyright notice and this permission", X"notice are preserved on all copies. All other rights reserved.", X"", X"Many formulas and tables are based, with permission, on material found in", X"\"Astronomy with your Personal Computer\"", X"by Dr. Peter Duffett-Smith, Cambridge University Press, (c) 1985", X"", X"type any key to continue..." X}; Xcredits() X{ X int r = 6; /* first row of credits message */ X int l; X X c_erase(); X for (l = 0; l < sizeof(cre)/sizeof(cre[0]); l++) X f_string (r++, (NC - strlen(cre[l]))/2, cre[l]); X (void) read_char(); /* wait for any char to continue */ X} END_OF_FILE if test 9448 -ne `wc -c <'version.c'`; then echo shar: \"'version.c'\" unpacked with wrong size! fi # end of 'version.c' fi echo shar: End of archive 3 \(of 6\). cp /dev/null ark3isdone MISSING="" for I in 1 2 3 4 5 6 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 6 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0