| 1 | #include <stdio.h>
 | 
|---|
| 2 | #include <math.h>
 | 
|---|
| 3 | 
 | 
|---|
| 4 | #include "astro.h"
 | 
|---|
| 5 | 
 | 
|---|
| 6 | static void precess_hiprec (double mjd1, double mjd2, double *ra, double *dec);
 | 
|---|
| 7 | 
 | 
|---|
| 8 | 
 | 
|---|
| 9 | #define DCOS(x)         cos(degrad(x))
 | 
|---|
| 10 | #define DSIN(x)         sin(degrad(x))
 | 
|---|
| 11 | #define DASIN(x)        raddeg(asin(x))
 | 
|---|
| 12 | #define DATAN2(y,x)     raddeg(atan2((y),(x)))
 | 
|---|
| 13 | 
 | 
|---|
| 14 | /* corrects ra and dec, both in radians, for precession from epoch 1 to epoch 2.
 | 
|---|
| 15 |  * the epochs are given by their modified JDs, mjd1 and mjd2, respectively.
 | 
|---|
| 16 |  * N.B. ra and dec are modifed IN PLACE.
 | 
|---|
| 17 |  */
 | 
|---|
| 18 | void
 | 
|---|
| 19 | precess (
 | 
|---|
| 20 | double mjd1, double mjd2,       /* initial and final epoch modified JDs */
 | 
|---|
| 21 | double *ra, double *dec)        /* ra/dec for mjd1 in, for mjd2 out */
 | 
|---|
| 22 | {
 | 
|---|
| 23 |         precess_hiprec (mjd1, mjd2, ra, dec);
 | 
|---|
| 24 | }
 | 
|---|
| 25 | 
 | 
|---|
| 26 | /*
 | 
|---|
| 27 |  * Copyright (c) 1990 by Craig Counterman. All rights reserved.
 | 
|---|
| 28 |  *
 | 
|---|
| 29 |  * This software may be redistributed freely, not sold.
 | 
|---|
| 30 |  * This copyright notice and disclaimer of warranty must remain
 | 
|---|
| 31 |  *    unchanged. 
 | 
|---|
| 32 |  *
 | 
|---|
| 33 |  * No representation is made about the suitability of this
 | 
|---|
| 34 |  * software for any purpose.  It is provided "as is" without express or
 | 
|---|
| 35 |  * implied warranty, to the extent permitted by applicable law.
 | 
|---|
| 36 |  *
 | 
|---|
| 37 |  * Rigorous precession. From Astronomical Ephemeris 1989, p. B18
 | 
|---|
| 38 |  *
 | 
|---|
| 39 |  * 96-06-20 Hayo Hase <hase@wettzell.ifag.de>: theta_a corrected
 | 
|---|
| 40 |  */
 | 
|---|
| 41 | static void
 | 
|---|
| 42 | precess_hiprec (
 | 
|---|
| 43 | double mjd1, double mjd2,       /* initial and final epoch modified JDs */
 | 
|---|
| 44 | double *ra, double *dec)        /* ra/dec for mjd1 in, for mjd2 out */
 | 
|---|
| 45 | {
 | 
|---|
| 46 |         static double last_mjd1 = -213.432, last_from;
 | 
|---|
| 47 |         static double last_mjd2 = -213.432, last_to;
 | 
|---|
| 48 |         double zeta_A, z_A, theta_A;
 | 
|---|
| 49 |         double T;
 | 
|---|
| 50 |         double A, B, C;
 | 
|---|
| 51 |         double alpha, delta;
 | 
|---|
| 52 |         double alpha_in, delta_in;
 | 
|---|
| 53 |         double from_equinox, to_equinox;
 | 
|---|
| 54 |         double alpha2000, delta2000;
 | 
|---|
| 55 | 
 | 
|---|
| 56 |         /* convert mjds to years;
 | 
|---|
| 57 |          * avoid the remarkably expensive calls to mjd_year()
 | 
|---|
| 58 |          */
 | 
|---|
| 59 |         if (last_mjd1 == mjd1)
 | 
|---|
| 60 |             from_equinox = last_from;
 | 
|---|
| 61 |         else {
 | 
|---|
| 62 |             mjd_year (mjd1, &from_equinox);
 | 
|---|
| 63 |             last_mjd1 = mjd1;
 | 
|---|
| 64 |             last_from = from_equinox;
 | 
|---|
| 65 |         }
 | 
|---|
| 66 |         if (last_mjd2 == mjd2)
 | 
|---|
| 67 |             to_equinox = last_to;
 | 
|---|
| 68 |         else {
 | 
|---|
| 69 |             mjd_year (mjd2, &to_equinox);
 | 
|---|
| 70 |             last_mjd2 = mjd2;
 | 
|---|
| 71 |             last_to = to_equinox;
 | 
|---|
| 72 |         }
 | 
|---|
| 73 | 
 | 
|---|
| 74 |         /* convert coords in rads to degs */
 | 
|---|
| 75 |         alpha_in = raddeg(*ra);
 | 
|---|
| 76 |         delta_in = raddeg(*dec);
 | 
|---|
| 77 | 
 | 
|---|
| 78 |         /* precession progresses about 1 arc second in .047 years */
 | 
|---|
| 79 |         /* From from_equinox to 2000.0 */
 | 
|---|
| 80 |         if (fabs (from_equinox-2000.0) > .02) {
 | 
|---|
| 81 |             T = (from_equinox - 2000.0)/100.0;
 | 
|---|
| 82 |             zeta_A  = 0.6406161* T + 0.0000839* T*T + 0.0000050* T*T*T;
 | 
|---|
| 83 |             z_A     = 0.6406161* T + 0.0003041* T*T + 0.0000051* T*T*T;
 | 
|---|
| 84 |             theta_A = 0.5567530* T - 0.0001185* T*T - 0.0000116* T*T*T;
 | 
|---|
| 85 | 
 | 
|---|
| 86 |             A = DSIN(alpha_in - z_A) * DCOS(delta_in);
 | 
|---|
| 87 |             B = DCOS(alpha_in - z_A) * DCOS(theta_A) * DCOS(delta_in)
 | 
|---|
| 88 |               + DSIN(theta_A) * DSIN(delta_in);
 | 
|---|
| 89 |             C = -DCOS(alpha_in - z_A) * DSIN(theta_A) * DCOS(delta_in)
 | 
|---|
| 90 |               + DCOS(theta_A) * DSIN(delta_in);
 | 
|---|
| 91 | 
 | 
|---|
| 92 |             alpha2000 = DATAN2(A,B) - zeta_A;
 | 
|---|
| 93 |             range (&alpha2000, 360.0);
 | 
|---|
| 94 |             delta2000 = DASIN(C);
 | 
|---|
| 95 |         } else {
 | 
|---|
| 96 |             /* should get the same answer, but this could improve accruacy */
 | 
|---|
| 97 |             alpha2000 = alpha_in;
 | 
|---|
| 98 |             delta2000 = delta_in;
 | 
|---|
| 99 |         };
 | 
|---|
| 100 | 
 | 
|---|
| 101 | 
 | 
|---|
| 102 |         /* From 2000.0 to to_equinox */
 | 
|---|
| 103 |         if (fabs (to_equinox - 2000.0) > .02) {
 | 
|---|
| 104 |             T = (to_equinox - 2000.0)/100.0;
 | 
|---|
| 105 |             zeta_A  = 0.6406161* T + 0.0000839* T*T + 0.0000050* T*T*T;
 | 
|---|
| 106 |             z_A     = 0.6406161* T + 0.0003041* T*T + 0.0000051* T*T*T;
 | 
|---|
| 107 |             theta_A = 0.5567530* T - 0.0001185* T*T - 0.0000116* T*T*T;
 | 
|---|
| 108 | 
 | 
|---|
| 109 |             A = DSIN(alpha2000 + zeta_A) * DCOS(delta2000);
 | 
|---|
| 110 |             B = DCOS(alpha2000 + zeta_A) * DCOS(theta_A) * DCOS(delta2000)
 | 
|---|
| 111 |               - DSIN(theta_A) * DSIN(delta2000);
 | 
|---|
| 112 |             C = DCOS(alpha2000 + zeta_A) * DSIN(theta_A) * DCOS(delta2000)
 | 
|---|
| 113 |               + DCOS(theta_A) * DSIN(delta2000);
 | 
|---|
| 114 | 
 | 
|---|
| 115 |             alpha = DATAN2(A,B) + z_A;
 | 
|---|
| 116 |             range(&alpha, 360.0);
 | 
|---|
| 117 |             delta = DASIN(C);
 | 
|---|
| 118 |         } else {
 | 
|---|
| 119 |             /* should get the same answer, but this could improve accruacy */
 | 
|---|
| 120 |             alpha = alpha2000;
 | 
|---|
| 121 |             delta = delta2000;
 | 
|---|
| 122 |         };
 | 
|---|
| 123 | 
 | 
|---|
| 124 |         *ra = degrad(alpha);
 | 
|---|
| 125 |         *dec = degrad(delta);
 | 
|---|
| 126 | }
 | 
|---|
| 127 | 
 | 
|---|
| 128 | #if 0
 | 
|---|
| 129 | static void
 | 
|---|
| 130 | precess_fast (
 | 
|---|
| 131 | double mjd1, double mjd2,       /* initial and final epoch modified JDs */
 | 
|---|
| 132 | double *ra, double *dec)        /* ra/dec for mjd1 in, for mjd2 out */
 | 
|---|
| 133 | {
 | 
|---|
| 134 | #define N       degrad (20.0468/3600.0)
 | 
|---|
| 135 | #define M       hrrad (3.07234/3600.0)
 | 
|---|
| 136 |         double nyrs;
 | 
|---|
| 137 | 
 | 
|---|
| 138 |         nyrs = (mjd2 - mjd1)/365.2425;
 | 
|---|
| 139 |         *dec += N * cos(*ra) * nyrs;
 | 
|---|
| 140 |         *ra += (M + (N * sin(*ra) * tan(*dec))) * nyrs;
 | 
|---|
| 141 |         range (ra, 2.0*PI);
 | 
|---|
| 142 | }
 | 
|---|
| 143 | #endif
 | 
|---|
| 144 | 
 | 
|---|
| 145 | /* For RCS Only -- Do Not Edit */
 | 
|---|
| 146 | static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: precess.c,v $ $Date: 2005-08-21 10:02:39 $ $Revision: 1.5 $ $Name: not supported by cvs2svn $"};
 | 
|---|