Ignore:
Timestamp:
Jun 15, 2004, 6:54:12 PM (21 years ago)
Author:
cmv
Message:

nouvelle version de xephem/libastro (3.6) cmv 15/6/04

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/SophyaExt/XephemAstroLib/circum.c

    r1719 r2551  
    99#include <stdio.h>
    1010#include <math.h>
    11 #if defined(__STDC__)
    1211#include <stdlib.h>
    13 #endif
    14 
    15 #include "P_.h"
     12
    1613#include "astro.h"
    17 #include "circum.h"
    1814#include "preferences.h"
    1915
    2016
    21 static int obj_planet P_((Now *np, Obj *op));
    22 static int obj_fixed P_((Now *np, Obj *op));
    23 static int obj_elliptical P_((Now *np, Obj *op));
    24 static int obj_hyperbolic P_((Now *np, Obj *op));
    25 static int obj_parabolic P_((Now *np, Obj *op));
    26 static int sun_cir P_((Now *np, Obj *op));
    27 static int moon_cir P_((Now *np, Obj *op));
    28 static void cir_sky P_((Now *np, double lpd, double psi, double rp, double *rho,
    29     double lam, double bet, double lsn, double rsn, Obj *op));
    30 static void cir_pos P_((Now *np, double bet, double lam, double *rho, Obj *op));
    31 static void elongation P_((double lam, double bet, double lsn, double *el));
    32 static void deflect P_((double mjd1, double lpd, double psi, double rsn,
    33     double lsn, double rho, double *ra, double *dec));
    34 static double h_albsize P_((double H));
     17static int obj_planet (Now *np, Obj *op);
     18static int obj_binary (Now *np, Obj *op);
     19static int obj_2binary (Now *np, Obj *op);
     20static int obj_fixed (Now *np, Obj *op);
     21static int obj_elliptical (Now *np, Obj *op);
     22static int obj_hyperbolic (Now *np, Obj *op);
     23static int obj_parabolic (Now *np, Obj *op);
     24static int sun_cir (Now *np, Obj *op);
     25static int moon_cir (Now *np, Obj *op);
     26static double solveKepler (double M, double e);
     27static void binaryStarOrbit (double t, double T, double e, double o, double O,
     28    double i, double a, double P, double *thetap, double *rhop);
     29static void cir_sky (Now *np, double lpd, double psi, double rp, double *rho,
     30    double lam, double bet, double lsn, double rsn, Obj *op);
     31static void cir_pos (Now *np, double bet, double lam, double *rho, Obj *op);
     32static void elongation (double lam, double bet, double lsn, double *el);
     33static void deflect (double mjd1, double lpd, double psi, double rsn,
     34    double lsn, double rho, double *ra, double *dec);
     35static double h_albsize (double H);
    3536
    3637/* given a Now and an Obj, fill in the approprirate s_* fields within Obj.
     
    3839 */
    3940int
    40 obj_cir (np, op)
    41 Now *np;
    42 Obj *op;
    43 {
     41obj_cir (Now *np, Obj *op)
     42{
     43        op->o_flags &= ~NOCIRCUM;
    4444        switch (op->o_type) {
     45        case BINARYSTAR: return (obj_binary (np, op));
    4546        case FIXED:      return (obj_fixed (np, op));
    4647        case ELLIPTICAL: return (obj_elliptical (np, op));
     
    5051        case PLANET:     return (obj_planet (np, op));
    5152        default:
    52             printf ("obj_cir() called with type %d\n", op->o_type);
    53             exit(1);
     53            printf ("obj_cir() called with type %d %s\n", op->o_type, op->o_name);
     54            abort();
    5455            return (-1);        /* just for lint */
    5556        }
     
    5758
    5859static int
    59 obj_planet (np, op)
    60 Now *np;
    61 Obj *op;
     60obj_planet (Now *np, Obj *op)
    6261{
    6362        double lsn, rsn;        /* true geoc lng of sun; dist from sn to earth*/
     
    6766        double lam, bet;        /* geocentric ecliptic long and lat */
    6867        double dia, mag;        /* angular diameter at 1 AU and magnitude */
    69         int p;
     68        PLCode p;
    7069
    7170        /* validate code and check for a few special cases */
    72         p = op->pl.pl_code;
     71        p = op->pl_code;
     72        if (p == SUN)
     73            return (sun_cir (np, op));
     74        if (p == MOON)
     75            return (moon_cir (np, op));
     76        if (op->pl_moon != X_PLANET)
     77            return (plmoon_cir (np, op));
    7378        if (p < 0 || p > MOON) {
    7479            printf ("unknown planet code: %d\n", p);
    75             exit(1);
    76         }
    77         else if (p == SUN)
    78             return (sun_cir (np, op));
    79         else if (p == MOON)
    80             return (moon_cir (np, op));
     80            abort();
     81        }
     82
     83        /* planet itself */
    8184
    8285        /* find solar ecliptical longitude and distance to sun from earth */
     
    99102
    100103static int
    101 obj_fixed (np, op)
    102 Now *np;
    103 Obj *op;
     104obj_binary (Now *np, Obj *op)
     105{
     106        /* always compute circumstances of primary */
     107        if (obj_fixed (np, op) < 0)
     108            return (0);
     109
     110        /* compute secondary only if requested, and always reset request flag */
     111        if (!op->b_2compute)
     112            return (0);
     113        op->b_2compute = 0;
     114        return (obj_2binary (np, op));
     115}
     116
     117/* compute position of secondary component of a BINARYSTAR */
     118static int
     119obj_2binary (Now *np, Obj *op)
     120{
     121        if (op->b_nbp > 0) {
     122            /* we just have discrete pa/sep, project each from primary */
     123            int i;
     124            for (i = 0; i < op->b_nbp; i++) {
     125                BinPos *bp = &op->b_bp[i];
     126                bp->bp_dec = op->s_dec + bp->bp_sep*cos(bp->bp_pa);
     127                bp->bp_ra = op->s_ra + bp->bp_sep*sin(bp->bp_pa)/cos(op->s_dec);
     128            }
     129        } else {
     130            BinOrbit *bp = &op->b_bo;
     131            double t, theta, rho;
     132
     133            mjd_year (mjd, &t);
     134            binaryStarOrbit (t, bp->bo_T, bp->bo_e, bp->bo_o, bp->bo_O,
     135                                bp->bo_i, bp->bo_a, bp->bo_P, &theta, &rho);
     136            bp->bo_pa = (float)theta;
     137            bp->bo_sep = (float)rho;
     138            rho = degrad(rho/3600.);    /* arc secs to rads */
     139            bp->bo_dec = op->s_dec + rho*cos(theta);
     140            bp->bo_ra =  op->s_ra  + rho*sin(theta)/cos(op->s_dec);
     141        }
     142
     143        return (0);
     144}
     145
     146/* from W. M. Smart */
     147static void
     148binaryStarOrbit (
     149double t,               /* desired ephemeris epoch, year */
     150double T,               /* epoch of periastron, year */
     151double e,               /* eccentricity */
     152double o,               /* argument of periastron, degrees */
     153double O,               /* ascending node, degrees */
     154double i,               /* inclination, degrees */
     155double a,               /* semi major axis, arcsecs */
     156double P,               /* period, years */
     157double *thetap,         /* position angle, rads E of N */
     158double *rhop)           /* separation, arcsecs */
     159{
     160        double M, E, cosE, nu, cosnu, r, rho, theta;
     161
     162        /* find mean anomaly, insure 0..2*PI */
     163        M = 2*PI/P*(t-T);
     164        range (&M, 2*PI);
     165
     166        /* solve for eccentric anomaly */
     167        E = solveKepler (M, e);
     168        cosE = cos(E);
     169
     170        /* find true anomaly and separation */
     171        cosnu = (cosE - e)/(1.0 - e*cosE);
     172        r = a*(1.0 - e*e)/(1.0 + e*cosnu);
     173        nu = acos(cosnu);
     174        if (E > PI)
     175            nu = -nu;
     176
     177        /* project onto sky */
     178        theta = atan(tan(nu+degrad(o))*cos(degrad(i))) + degrad(O);
     179        rho = r*cos(nu+degrad(o))/cos(theta-degrad(O));
     180        if (rho < 0) {
     181            theta += PI;
     182            rho = -rho;
     183        }
     184        range (&theta, 2*PI);
     185
     186        *thetap = theta;
     187        *rhop = rho;
     188}
     189
     190/* solve kepler equation using Newton-Raphson search.
     191 * Charles and Tatum have shown it always converges starting with PI.
     192 */
     193static double
     194solveKepler (double M, double e)
     195{
     196        double E, Eprime = PI;
     197
     198        do {
     199            double cosE = cos(Eprime);
     200            E = Eprime;
     201            Eprime = (M - e*(E*cosE - sin(E)))/(1.0 - e*cosE);
     202        } while (fabs(E-Eprime) > 1e-7);
     203
     204        return (Eprime);
     205}
     206
     207static int
     208obj_fixed (Now *np, Obj *op)
    104209{
    105210        double lsn, rsn;        /* true geoc lng of sun, dist from sn to earth*/
     
    108213        double el;              /* elongation */
    109214        double alt, az;         /* current alt, az */
    110         double ra, dec;         /* ra and dec at epoch of date */
     215        double ra, dec;         /* ra and dec at equinox of date */
     216        double rpm, dpm;        /* astrometric ra and dec with PM to now */
    111217        double lst;
    112218
    113         if (epoch != EOD && (float)epoch != op->f_epoch) {
    114             /* want a certain epoch -- if it's not what the database is at
    115              * we change the original to save time next time assuming the
    116              * user is likely to stick with this for a while.
    117              */
    118             double tra = op->f_RA, tdec = op->f_dec;
    119             float tepoch = (float)epoch;        /* compare w/float precision */
    120             precess (op->f_epoch, tepoch, &tra, &tdec);
    121             op->f_epoch = tepoch;
    122             op->f_RA = (float)tra;
    123             op->f_dec = (float)tdec;
    124         }
    125 
    126         /* set ra/dec to astrometric @ epoch of date */
    127         ra = op->f_RA;
    128         dec = op->f_dec;
     219        /* on the assumption that the user will stick with their chosen display
     220         * epoch for a while, we move the defining values to match and avoid
     221         * precession for every call until it is changed again.
     222         * N.B. only compare and store jd's to lowest precission (f_epoch).
     223         * N.B. maintaining J2k ref (which is arbitrary) helps avoid accum err
     224         */
     225        if (epoch != EOD && (float)epoch != (float)op->f_epoch) {
     226            double pr = op->f_RA, pd = op->f_dec, fe = (float)epoch;
     227            /* first bring back to 2k */
     228            precess (op->f_epoch, J2000, &pr, &pd);
     229            pr += op->f_pmRA*(J2000-op->f_epoch);
     230            pd += op->f_pmdec*(J2000-op->f_epoch);
     231            /* then to epoch */
     232            pr += op->f_pmRA*(fe-J2000);
     233            pd += op->f_pmdec*(fe-J2000);
     234            precess (J2000, fe, &pr, &pd);
     235            op->f_RA = (float)pr;
     236            op->f_dec = (float)pd;
     237            op->f_epoch = (float)fe;
     238        }
     239
     240        /* apply proper motion .. assume pm epoch reference equals equinox */
     241        rpm = op->f_RA + op->f_pmRA*(mjd-op->f_epoch);
     242        dpm = op->f_dec + op->f_pmdec*(mjd-op->f_epoch);
     243
     244        /* set ra/dec to astrometric @ equinox of date */
     245        ra = rpm;
     246        dec = dpm;
    129247        precess (op->f_epoch, mjed, &ra, &dec);
    130248
     
    154272        } else {
    155273            /* annual parallax at time mjd is to be added here, too, but
    156              * technically in the frame of epoch (usually different from mjd)
     274             * technically in the frame of equinox (usually different from mjd)
    157275             */
    158             op->s_ra = op->f_RA;        /* already precessed */
    159             op->s_dec = op->f_dec;
     276            op->s_ra = rpm;
     277            op->s_dec = dpm;
    160278        }
    161279
     
    184302 */
    185303static int
    186 obj_elliptical (np, op)
    187 Now *np;
    188 Obj *op;
     304obj_elliptical (Now *np, Obj *op)
    189305{
    190306        double lsn, rsn;        /* true geoc lng of sun; dist from sn to earth*/
     
    230346
    231347            tp = mjed - dt - (op->e_cepoch - op->e_M/e_n);
    232             vrc (&nu, &rp, tp, op->e_e, op->e_a*(1-op->e_e));
     348            if (vrc (&nu, &rp, tp, op->e_e, op->e_a*(1-op->e_e)) < 0)
     349                op->o_flags |= NOCIRCUM;
    233350            nu = degrad(nu);
    234351            lo = nu + om;
     
    288405 */
    289406static int
    290 obj_hyperbolic (np, op)
    291 Now *np;
    292 Obj *op;
     407obj_hyperbolic (Now *np, Obj *op)
    293408{
    294409        double lsn, rsn;        /* true geoc lng of sun; dist from sn to earth*/
     
    309424        double e;               /* fast eccentricity */
    310425        double ll=0, sll, cll;  /* helio angle between object and earth */
    311         double n;               /* mean daily motion */
    312426        double mag;             /* magnitude */
    313427        double a;               /* mean distance */
     
    323437        e = op->h_e;
    324438        a = op->h_qp/(e - 1.0);
    325         n = .98563/sqrt(a*a*a);
    326439
    327440        /* correct for light time by computing position at time mjd, then
     
    337450
    338451            tp = mjed - dt - op->h_ep;
    339             vrc (&nu, &rp, tp, op->h_e, op->h_qp);
     452            if (vrc (&nu, &rp, tp, op->h_e, op->h_qp) < 0)
     453                op->o_flags |= NOCIRCUM;
    340454            nu = degrad(nu);
    341455            lo = nu + om;
     
    382496 */
    383497static int
    384 obj_parabolic (np, op)
    385 Now *np;
    386 Obj *op;
     498obj_parabolic (Now *np, Obj *op)
    387499{
    388500        double lsn, rsn;        /* true geoc lng of sun; dist from sn to earth*/
     
    422534 */
    423535static int
    424 sun_cir (np, op)
    425 Now *np;
    426 Obj *op;
     536sun_cir (Now *np, Obj *op)
    427537{
    428538        double lsn, rsn;        /* true geoc lng of sun; dist from sn to earth*/
     
    452562 */
    453563static int
    454 moon_cir (np, op)
    455 Now *np;
    456 Obj *op;
     564moon_cir (Now *np, Obj *op)
    457565{
    458566        double lsn, rsn;        /* true geoc lng of sun; dist from sn to earth*/
     
    480588
    481589        /* TODO: improve mag; this is based on a flat moon model. */
    482         set_smag (op, -12.7 + 2.5*(log10(PI) - log10(PI/2*(1+1.e-6-cos(el)))));
     590        i = -12.7 + 2.5*(log10(PI) - log10(PI/2*(1+1.e-6-cos(el))))
     591                                        + 5*log10(edistau/.0025) /* dist */;
     592        set_smag (op, i);
    483593
    484594        /* find phase -- allow for projection effects */
     
    500610 */
    501611static void
    502 cir_sky (np, lpd, psi, rp, rho, lam, bet, lsn, rsn, op)
    503 Now *np;
    504 double lpd, psi;        /* heliocentric ecliptic long and lat */
    505 double rp;              /* dist from sun */
    506 double *rho;            /* dist from earth: in as geo, back as geo or topo */
    507 double lam, bet;        /* true geocentric ecliptic long and lat */
    508 double lsn, rsn;        /* true geoc lng of sun; dist from sn to earth*/
    509 Obj *op;
     612cir_sky (
     613Now *np,
     614double lpd,             /* heliocentric ecliptic longitude */
     615double psi,             /* heliocentric ecliptic lat */
     616double rp,              /* dist from sun */
     617double *rho,            /* dist from earth: in as geo, back as geo or topo */
     618double lam,             /* true geocentric ecliptic long */
     619double bet,             /* true geocentric ecliptic lat */
     620double lsn,             /* true geoc lng of sun */
     621double rsn,             /* dist from sn to earth*/
     622Obj *op)
    510623{
    511624        double el;              /* elongation */
     
    546659 *   refract    --> alt/az      observed --> output
    547660 *
    548  * algorithm at fixed epoch:
     661 * algorithm at fixed equinox:
    549662 *   ecl_eq     --> ra/dec      geocentric mean equatoreal EOD (via mean obliq)
    550663 *   deflect    --> ra/dec        relativistic deflection [for alt/az only]
     
    558671 */
    559672static void
    560 cir_pos (np, bet, lam, rho, op)
    561 Now *np;
    562 double bet, lam;/* geo lat/long (mean ecliptic of date) */
    563 double *rho;    /* in: geocentric dist in AU; out: geo- or topocentic dist */
    564 Obj *op;        /* object to set s_ra/dec as per epoch */
     673cir_pos (
     674Now *np,
     675double bet,     /* geo lat (mean ecliptic of date) */
     676double lam,     /* geo long (mean ecliptic of date) */
     677double *rho,    /* in: geocentric dist in AU; out: geo- or topocentic dist */
     678Obj *op)        /* object to set s_ra/dec as per equinox */
    565679{
    566680        double ra, dec;         /* apparent ra/dec, corrected for nut/ab */
     
    649763 */
    650764static void
    651 elongation (lam, bet, lsn, el)
    652 double lam, bet, lsn;
    653 double *el;
     765elongation (double lam, double bet, double lsn, double *el)
    654766{
    655767        *el = acos(cos(bet)*cos(lam-lsn));
     
    675787 */
    676788static void
    677 deflect (mjd1, lpd, psi, lsn, rsn, rho, ra, dec)
    678 double mjd1;            /* epoch */
    679 double lpd, psi;        /* heliocentric ecliptical long / lat */
    680 double rsn, lsn;        /* distance and longitude of sun */
    681 double rho;             /* geocentric distance */
    682 double *ra, *dec;       /* geocentric equatoreal */
     789deflect (
     790double mjd1,            /* equinox */
     791double lpd, double psi, /* heliocentric ecliptical long / lat */
     792double rsn, double lsn, /* distance and longitude of sun */
     793double rho,             /* geocentric distance */
     794double *ra, double *dec)/* geocentric equatoreal */
    683795{
    684796        double hra, hdec;       /* object heliocentric equatoreal */
     
    742854 */
    743855static double
    744 h_albsize (H)
    745 double H;
     856h_albsize (double H)
    746857{
    747858        return (3600*raddeg(.707*1500*pow(2.51,(18-H)/2)/MAU));
     
    749860
    750861/* For RCS Only -- Do Not Edit */
    751 static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: circum.c,v $ $Date: 2001-10-22 12:08:26 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
     862static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: circum.c,v $ $Date: 2004-06-15 16:52:37 $ $Revision: 1.3 $ $Name: not supported by cvs2svn $"};
Note: See TracChangeset for help on using the changeset viewer.