/* * The entry, domoon(), is intended to be called by the AA.ARC * ephemeris calculator. It calculates the Moon's apparent position. * Corrections for nutation and light time are included, but the * required routines for this are given as separate files in AA.ARC. * Note that the difference between Ephemeris and Universal * time is significant here, since the Moon moves in right * ascension at the rate of about 2s/minute. * */ #include "kep.h" #ifdef ANSIPROT int gmoon (double, double *, double *); int moonll (double, double *, double *); #else int gmoon (), moonll (); #endif extern double aearth, au; static double FAR ra; /* Right Ascension */ static double FAR dec; /* Declination */ double FAR Rearth; /* Calculate geometric position of the Moon and apply * approximate corrections to find apparent position, * phase of the Moon, etc. for AA.ARC. */ int domoon() { int i, prtsav; double ra0, dec0; double x, y, z, lon0; double pp[3], qq[3], pe[3], re[3], moonpp[3], moonpol[3]; /* Geometric equatorial coordinates of the earth. */ for (i = 0; i < 3; i++) re[i] = rearth[i]; /* Run the orbit calculation twice, at two different times, * in order to find the rate of change of R.A. and Dec. */ /* Calculate for 0.001 day ago */ prtsav = prtflg; prtflg = 0; /* disable display */ moonll(TDT-0.001, moonpp, moonpol); ra0 = ra; dec0 = dec; lon0 = moonpol[0]; prtflg = prtsav; /* Calculate for present instant. */ moonll(TDT, moonpp, moonpol); if(prtflg) printf("Geometric lon %.3f deg, lat %.3f deg, rad %.4e au\n", RTD * obpolar[0], RTD * obpolar[1], obpolar[2]); prtflg = 0; /* The rates of change. These are used by altaz() to * correct the time of rising, transit, and setting. */ dradt = ra - ra0; if (dradt >= PI) dradt = dradt - 2.0 * PI; if (dradt <= -PI) dradt = dradt + 2.0 * PI; dradt = 1000.0 * dradt; ddecdt = 1000.0*(dec-dec0); /* Rate of change in longitude, degrees per day * used for phase of the moon */ lon0 = 1000.0*RTD*(moonpol[0] - lon0); /* Get apparent coordinates for the earth. */ z = re[0] * re[0] + re[1] * re[1] + re[2] * re[2]; z = sqrt(z); for (i = 0; i < 3; i++) re[i] /= z; annuab( re ); /* aberration of light. */ /* pe[0] -= STR * (20.496/(RTS*pe[2])); */ precess( re, TDT, -1 ); nutate( TDT, re ); for (i = 0; i < 3; i++) re[i] *= z; lonlat( re, TDT, pe, 0 ); prtflg = prtsav; /* reenable display */ /* Find sun-moon-earth angles */ for( i=0; i<3; i++ ) qq[i] = re[i] + moonpp[i]; angles( moonpp, qq, re ); /* Display answers */ if( prtflg ) { printf( "Apparent geocentric longitude %.3f deg", RTD * moonpol[0] ); printf( " latitude %.3f deg\n", RTD * moonpol[1] ); printf( "Distance %.3f Earth-radii\n", moonpol[2]/Rearth ); printf( "Horizontal parallax" ); x = Rearth/moonpol[2]; dms( asin(x) ); printf( "Semidiameter" ); x = 0.272453 * x + 0.0799/RTS; /* AA page L6 */ dms( x ); x = RTD * acos(-ep); /* x = 180.0 - RTD * arcdot (re, pp); */ printf( "\nElongation from sun %.2f deg,", x ); x = 0.5 * (1.0 + pq); printf( " Illuminated fraction %.2f\n", x ); /* Find phase of the Moon by comparing Moon's longitude * with Earth's longitude. * * The number of days before or past indicated phase is * estimated by assuming the true longitudes change linearly * with time. These rates are estimated for the date, but * do not stay constant. The error can exceed 0.15 day in 4 days. */ x = moonpol[0] - pe[0]; x = modtp( x ) * RTD; /* difference in longitude */ i = (int) (x/90); /* number of quarters */ x = (x - i*90.0); /* phase angle mod 90 degrees */ /* days per degree of phase angle */ z = moonpol[2]/(12.3685 * 0.00257357); if( x > 45.0 ) { y = -(x - 90.0)*z; if( y > 1.0 ) printf( "Phase %.1f days before ", y ); else printf( "Phase %.2f days before ", y ); i = (i+1) & 3; } else { y = x*z; if( y > 1.0 ) printf( "Phase %.1f days past ", y ); else printf( "Phase %.2f days past ", y ); } switch(i) { case 0: printf( "Full Moon\n" ); break; case 1: printf( "Third Quarter\n" ); break; case 2: printf( "New Moon\n" ); break; case 3: printf( "First Quarter\n" ); break; } printf( " Apparent: R.A." ); hms(ra); printf( "Declination" ); dms(dec); printf( "\n" ); } /* if prtflg */ /* Compute and display topocentric position (altaz.c) */ pp[0] = ra; pp[1] = dec; pp[2] = moonpol[2]; altaz( pp, UT ); return(0); } /* Calculate apparent latitude, longitude, and horizontal parallax * of the Moon at Julian date J. */ int moonll(J, rect, pol) double J, rect[], pol[]; { double cosB, sinB, cosL, sinL, y, z; double qq[3], pp[3]; int i; /* Compute obliquity of the ecliptic, coseps, and sineps. */ epsiln( J ); /* Get geometric coordinates of the Moon. */ gmoon (J, rect, pol); /* Post the geometric ecliptic longitude and latitude, in radians, * and the radius in au. */ obpolar[0] = pol[0]; obpolar[1] = pol[1]; obpolar[2] = pol[2]; /* Light time correction to longitude, * about 0.7". */ pol[0] -= 0.0118 * DTR * Rearth / pol[2]; /* convert to equatorial system of date */ cosB = cos(pol[1]); sinB = sin(pol[1]); cosL = cos(pol[0]); sinL = sin(pol[0]); rect[0] = cosB*cosL; rect[1] = coseps*cosB*sinL - sineps*sinB; rect[2] = sineps*cosB*sinL + coseps*sinB; /* Rotate to J2000. */ precess( rect, TDT, 1 ); /* Find Euclidean vectors and angles between earth, object, and the sun */ for( i=0; i<3; i++ ) { pp[i] = rect[i] * pol[2]; qq[i] = rearth[i] + pp[i]; } angles( pp, qq, rearth ); /* Make rect a unit vector. */ /* for (i = 0; i < 3; i++) */ /* rect[i] /= EO; */ /* Correct position for light deflection. (Ignore.) */ /* relativity( rect, qq, rearth ); */ /* Aberration of light. The Astronomical Almanac (Section D, Daily Polynomial Coefficients) seems to omit this, even though the reference ephemeris is inertial. */ /* annuab (rect); */ /* Precess to date. */ precess( rect, TDT, -1 ); /* Correct for nutation at date TDT. */ nutate( TDT, rect ); /* Apparent geocentric right ascension and declination. */ ra = zatan2(rect[0],rect[1]); dec = asin(rect[2]); /* For apparent ecliptic coordinates, rotate from the true equator into the ecliptic of date. */ cosL = cos(eps+nuto); sinL = sin(eps+nuto); y = cosL * rect[1] + sinL * rect[2]; z = -sinL * rect[1] + cosL * rect[2]; pol[0] = zatan2( rect[0], y ); pol[1] = asin(z); /* Restore earth-moon distance. */ for( i=0; i<3; i++ ) rect[i] *= EO; return(0); }