| 1 | #include "slalib.h"
|
|---|
| 2 | #include "slamac.h"
|
|---|
| 3 | void slaMoon ( int iy, int id, float fd, float pv[6] )
|
|---|
| 4 | /*
|
|---|
| 5 | ** - - - - - - - -
|
|---|
| 6 | ** s l a M o o n
|
|---|
| 7 | ** - - - - - - - -
|
|---|
| 8 | **
|
|---|
| 9 | ** Approximate geocentric position and velocity of the Moon
|
|---|
| 10 | ** (single precision).
|
|---|
| 11 | **
|
|---|
| 12 | ** Given:
|
|---|
| 13 | ** iy int year
|
|---|
| 14 | ** id int day in year (1 = Jan 1st)
|
|---|
| 15 | ** fd float fraction of day
|
|---|
| 16 | **
|
|---|
| 17 | ** Returned:
|
|---|
| 18 | ** pv float[6] Moon position & velocity vector
|
|---|
| 19 | **
|
|---|
| 20 | ** Notes:
|
|---|
| 21 | **
|
|---|
| 22 | ** 1 The date and time is TDB (loosely ET) in a Julian calendar
|
|---|
| 23 | ** which has been aligned to the ordinary Gregorian
|
|---|
| 24 | ** calendar for the interval 1900 March 1 to 2100 February 28.
|
|---|
| 25 | ** The year and day can be obtained by calling slaCalyd or
|
|---|
| 26 | ** slaClyd.
|
|---|
| 27 | **
|
|---|
| 28 | ** 2 The Moon 6-vector is Moon centre relative to Earth centre,
|
|---|
| 29 | ** mean equator and equinox of date. Position part, pv[0-2],
|
|---|
| 30 | ** is in AU; velocity part, pv[3-5], is in AU/sec.
|
|---|
| 31 | **
|
|---|
| 32 | ** 3 The position is accurate to better than 0.5 arcminute
|
|---|
| 33 | ** in direction and 1000 km in distance. The velocity
|
|---|
| 34 | ** is accurate to better than 0.5"/hour in direction and
|
|---|
| 35 | ** 4 m/s in distance. (RMS figures with respect to JPL DE200
|
|---|
| 36 | ** for the interval 1960-2025 are 14 arcsec and 0.2 arcsec/hour in
|
|---|
| 37 | ** longitude, 9 arcsec and 0.2 arcsec/hour in latitude, 350 km and
|
|---|
| 38 | ** 2 m/s in distance.) Note that the distance accuracy is
|
|---|
| 39 | ** comparatively poor because this routine is principally intended
|
|---|
| 40 | ** for computing topocentric direction.
|
|---|
| 41 | **
|
|---|
| 42 | ** 4 This routine is only a partial implementation of the original
|
|---|
| 43 | ** Meeus algorithm (reference below), which offers 4 times the
|
|---|
| 44 | ** accuracy in direction and 30 times the accuracy in distance
|
|---|
| 45 | ** when fully implemented (as it is in slaDmoon).
|
|---|
| 46 | **
|
|---|
| 47 | ** Reference:
|
|---|
| 48 | ** Meeus, l'Astronomie, June 1984, p348.
|
|---|
| 49 | **
|
|---|
| 50 | ** Defined in slamac.h: dmod
|
|---|
| 51 | **
|
|---|
| 52 | ** Last revision: 9 April 1998
|
|---|
| 53 | **
|
|---|
| 54 | ** Copyright P.T.Wallace. All rights reserved.
|
|---|
| 55 | */
|
|---|
| 56 |
|
|---|
| 57 | #define D2R 0.01745329252f /* Degrees to radians */
|
|---|
| 58 |
|
|---|
| 59 | #define RATCON 9.652743551e-12f /* Rate conversion factor: */
|
|---|
| 60 | /* D2R * D2R / (86400 * 365.25) */
|
|---|
| 61 |
|
|---|
| 62 | #define ERADAU 4.2635212653763e-5f /* Earth equatorial radius in AU */
|
|---|
| 63 | /* ( = 6378.137 / 149597870 ) */
|
|---|
| 64 |
|
|---|
| 65 | {
|
|---|
| 66 | int iy4, n;
|
|---|
| 67 | float yi, yf, t, elp, em, emp, d, f, v, dv, emn, empn, dn, fn, coeff,
|
|---|
| 68 | theta, el, del, b, db, p, dp, sp, r, dr, x, y, z, xd, yd, zd,
|
|---|
| 69 | sel, cel, sb, cb, rcb, rbd, w, eps, sineps, coseps;
|
|---|
| 70 |
|
|---|
| 71 | /*
|
|---|
| 72 | ** Coefficients for fundamental arguments
|
|---|
| 73 | **
|
|---|
| 74 | ** Fixed term (deg), term in t (deg & whole revs + fraction per year)
|
|---|
| 75 | **
|
|---|
| 76 | ** Moon's mean longitude
|
|---|
| 77 | */
|
|---|
| 78 | static float elp0 = 270.434164f;
|
|---|
| 79 | static float elp1 = 4812.678831f;
|
|---|
| 80 | static float elp1i = 4680.0f;
|
|---|
| 81 | static float elp1f = 132.678831f;
|
|---|
| 82 |
|
|---|
| 83 | /* Sun's mean anomaly */
|
|---|
| 84 | static float em0 = 358.475833f;
|
|---|
| 85 | static float em1 = 359.990498f;
|
|---|
| 86 | static float em1f = 359.990498f;
|
|---|
| 87 |
|
|---|
| 88 | /* Moon's mean anomaly */
|
|---|
| 89 | static float emp0 = 296.104608f;
|
|---|
| 90 | static float emp1 = 4771.988491f;
|
|---|
| 91 | static float emp1i = 4680.0f;
|
|---|
| 92 | static float emp1f = 91.988491f;
|
|---|
| 93 |
|
|---|
| 94 | /* Moon's mean elongation */
|
|---|
| 95 | static float d0 = 350.737486f;
|
|---|
| 96 | static float d1 = 4452.671142f;
|
|---|
| 97 | static float d1i = 4320.0f;
|
|---|
| 98 | static float d1f = 132.671142f;
|
|---|
| 99 |
|
|---|
| 100 | /* Mean distance of the Moon from its ascending node */
|
|---|
| 101 | static float f0 = 11.250889f;
|
|---|
| 102 | static float f1 = 4832.020251f;
|
|---|
| 103 | static float f1i = 4680.0f;
|
|---|
| 104 | static float f1f = 152.020251f;
|
|---|
| 105 |
|
|---|
| 106 | /*
|
|---|
| 107 | ** Coefficients for Moon longitude, latitude, parallax series
|
|---|
| 108 | */
|
|---|
| 109 | struct term {
|
|---|
| 110 | float coef; /* coefficient of L, B or P term (deg) */
|
|---|
| 111 | int nem; /* multiple of M in argument */
|
|---|
| 112 | int nemp; /* " " M' " " */
|
|---|
| 113 | int nd; /* " " D " " */
|
|---|
| 114 | int nf; /* " " F " " */
|
|---|
| 115 | };
|
|---|
| 116 |
|
|---|
| 117 | /*
|
|---|
| 118 | ** Longitude coeff M M' D F
|
|---|
| 119 | */
|
|---|
| 120 | static struct term tl[] = { { 6.288750f, 0, 1, 0, 0 },
|
|---|
| 121 | { 1.274018f, 0, -1, 2, 0 },
|
|---|
| 122 | { 0.658309f, 0, 0, 2, 0 },
|
|---|
| 123 | { 0.213616f, 0, 2, 0, 0 },
|
|---|
| 124 | { -0.185596f, 1, 0, 0, 0 },
|
|---|
| 125 | { -0.114336f, 0, 0, 0, 2 },
|
|---|
| 126 | { 0.058793f, 0, -2, 2, 0 },
|
|---|
| 127 | { 0.057212f, -1, -1, 2, 0 },
|
|---|
| 128 | { 0.053320f, 0, 1, 2, 0 },
|
|---|
| 129 | { 0.045874f, -1, 0, 2, 0 },
|
|---|
| 130 | { 0.041024f, -1, 1, 0, 0 },
|
|---|
| 131 | { -0.034718f, 0, 0, 1, 0 },
|
|---|
| 132 | { -0.030465f, 1, 1, 0, 0 },
|
|---|
| 133 | { 0.015326f, 0, 0, 2, -2 },
|
|---|
| 134 | { -0.012528f, 0, 1, 0, 2 },
|
|---|
| 135 | { -0.010980f, 0, -1, 0, 2 },
|
|---|
| 136 | { 0.010674f, 0, -1, 4, 0 },
|
|---|
| 137 | { 0.010034f, 0, 3, 0, 0 },
|
|---|
| 138 | { 0.008548f, 0, -2, 4, 0 },
|
|---|
| 139 | { -0.007910f, 1, -1, 2, 0 },
|
|---|
| 140 | { -0.006783f, 1, 0, 2, 0 },
|
|---|
| 141 | { 0.005162f, 0, 1, -1, 0 },
|
|---|
| 142 | { 0.005000f, 1, 0, 1, 0 },
|
|---|
| 143 | { 0.004049f, -1, 1, 2, 0 },
|
|---|
| 144 | { 0.003996f, 0, 2, 2, 0 },
|
|---|
| 145 | { 0.003862f, 0, 0, 4, 0 },
|
|---|
| 146 | { 0.003665f, 0, -3, 2, 0 },
|
|---|
| 147 | { 0.002695f, -1, 2, 0, 0 },
|
|---|
| 148 | { 0.002602f, 0, 1, -2, -2 },
|
|---|
| 149 | { 0.002396f, -1, -2, 2, 0 },
|
|---|
| 150 | { -0.002349f, 0, 1, 1, 0 },
|
|---|
| 151 | { 0.002249f, -2, 0, 2, 0 },
|
|---|
| 152 | { -0.002125f, 1, 2, 0, 0 },
|
|---|
| 153 | { -0.002079f, 2, 0, 0, 0 },
|
|---|
| 154 | { 0.002059f, -2, -1, 2, 0 },
|
|---|
| 155 | { -0.001773f, 0, 1, 2, -2 },
|
|---|
| 156 | { -0.001595f, 0, 0, 2, 2 },
|
|---|
| 157 | { 0.001220f, -1, -1, 4, 0 },
|
|---|
| 158 | { -0.001110f, 0, 2, 0, 2 } };
|
|---|
| 159 | static int NL = ( sizeof tl / sizeof ( struct term ) );
|
|---|
| 160 |
|
|---|
| 161 | /*
|
|---|
| 162 | ** Latitude coeff M M' D F
|
|---|
| 163 | */
|
|---|
| 164 | static struct term tb[] = { { 5.128189f, 0, 0, 0, 1 },
|
|---|
| 165 | { 0.280606f, 0, 1, 0, 1 },
|
|---|
| 166 | { 0.277693f, 0, 1, 0, -1 },
|
|---|
| 167 | { 0.173238f, 0, 0, 2, -1 },
|
|---|
| 168 | { 0.055413f, 0, -1, 2, 1 },
|
|---|
| 169 | { 0.046272f, 0, -1, 2, -1 },
|
|---|
| 170 | { 0.032573f, 0, 0, 2, 1 },
|
|---|
| 171 | { 0.017198f, 0, 2, 0, 1 },
|
|---|
| 172 | { 0.009267f, 0, 1, 2, -1 },
|
|---|
| 173 | { 0.008823f, 0, 2, 0, -1 },
|
|---|
| 174 | { 0.008247f, -1, 0, 2, -1 },
|
|---|
| 175 | { 0.004323f, 0, -2, 2, -1 },
|
|---|
| 176 | { 0.004200f, 0, 1, 2, 1 },
|
|---|
| 177 | { 0.003372f, -1, 0, -2, 1 },
|
|---|
| 178 | { 0.002472f, -1, -1, 2, 1 },
|
|---|
| 179 | { 0.002222f, -1, 0, 2, 1 },
|
|---|
| 180 | { 0.002072f, -1, -1, 2, -1 },
|
|---|
| 181 | { 0.001877f, -1, 1, 0, 1 },
|
|---|
| 182 | { 0.001828f, 0, -1, 4, -1 },
|
|---|
| 183 | { -0.001803f, 1, 0, 0, 1 },
|
|---|
| 184 | { -0.001750f, 0, 0, 0, 3 },
|
|---|
| 185 | { 0.001570f, -1, 1, 0, -1 },
|
|---|
| 186 | { -0.001487f, 0, 0, 1, 1 },
|
|---|
| 187 | { -0.001481f, 1, 1, 0, 1 },
|
|---|
| 188 | { 0.001417f, -1, -1, 0, 1 },
|
|---|
| 189 | { 0.001350f, -1, 0, 0, 1 },
|
|---|
| 190 | { 0.001330f, 0, 0, -1, 1 },
|
|---|
| 191 | { 0.001106f, 0, 3, 0, 1 },
|
|---|
| 192 | { 0.001020f, 0, 0, 4, -1 } };
|
|---|
| 193 | static int NB = ( sizeof tb / sizeof ( struct term ) );
|
|---|
| 194 |
|
|---|
| 195 | /*
|
|---|
| 196 | ** Parallax coeff M M' D F
|
|---|
| 197 | */
|
|---|
| 198 | static struct term tp[] = { { 0.950724f, 0, 0, 0, 0 },
|
|---|
| 199 | { 0.051818f, 0, 1, 0, 0 },
|
|---|
| 200 | { 0.009531f, 0, -1, 2, 0 },
|
|---|
| 201 | { 0.007843f, 0, 0, 2, 0 },
|
|---|
| 202 | { 0.002824f, 0, 2, 0, 0 } };
|
|---|
| 203 | static int NP = ( sizeof tp / sizeof ( struct term ) );
|
|---|
| 204 |
|
|---|
| 205 |
|
|---|
| 206 |
|
|---|
| 207 | /* Whole years & fraction of year, and years since J1900.0 */
|
|---|
| 208 | yi = (float) ( iy - 1900 );
|
|---|
| 209 | iy4 = iy >= 4 ? iy % 4 : 3 - ( -iy - 1 ) % 4 ;
|
|---|
| 210 | yf = ( (float) ( 4 * ( id - 1 / ( iy4 + 1 ) )
|
|---|
| 211 | - iy4 - 2 ) + ( 4.0f * fd ) ) / 1461.0f;
|
|---|
| 212 | t = yi + yf;
|
|---|
| 213 |
|
|---|
| 214 | /* Moon's mean longitude */
|
|---|
| 215 | elp = D2R * (float) dmod ( (double) ( elp0 + elp1i * yf + elp1f * t ),
|
|---|
| 216 | 360.0 );
|
|---|
| 217 |
|
|---|
| 218 | /* Sun's mean anomaly */
|
|---|
| 219 | em = D2R * (float) dmod ( (double) ( em0 + em1f * t ), 360.0 );
|
|---|
| 220 |
|
|---|
| 221 | /* Moon's mean anomaly */
|
|---|
| 222 | emp = D2R * (float) dmod ( (double) ( emp0 + emp1i * yf + emp1f * t ),
|
|---|
| 223 | 360.0 );
|
|---|
| 224 |
|
|---|
| 225 | /* Moon's mean elongation */
|
|---|
| 226 | d = D2R * (float) dmod ( (double) ( d0 + d1i * yf + d1f * t ), 360.0 );
|
|---|
| 227 |
|
|---|
| 228 | /* Mean distance of the Moon from its ascending node */
|
|---|
| 229 | f = D2R * (float) dmod ( (double) ( f0 + f1i * yf + f1f * t ), 360.0 );
|
|---|
| 230 |
|
|---|
| 231 | /* Longitude */
|
|---|
| 232 | v = 0.0f;
|
|---|
| 233 | dv = 0.0f;
|
|---|
| 234 | for ( n = NL -1; n >= 0; n-- ) {
|
|---|
| 235 | coeff = tl[n].coef;
|
|---|
| 236 | emn = (float) tl[n].nem;
|
|---|
| 237 | empn = (float) tl[n].nemp;
|
|---|
| 238 | dn = (float) tl[n].nd;
|
|---|
| 239 | fn = (float) tl[n].nf;
|
|---|
| 240 | theta = emn * em + empn * emp + dn * d + fn * f;
|
|---|
| 241 | v += coeff * ( (float) sin ( (double) theta ) );
|
|---|
| 242 | dv += coeff * ( (float) cos ( (double) theta ) ) *
|
|---|
| 243 | ( emn * em1 + empn * emp1 + dn * d1 + fn * f1 );
|
|---|
| 244 | }
|
|---|
| 245 | el = elp + D2R * v;
|
|---|
| 246 | del = RATCON * ( elp1 / D2R + dv );
|
|---|
| 247 |
|
|---|
| 248 | /* Latitude */
|
|---|
| 249 | v = 0.0f;
|
|---|
| 250 | dv = 0.0f;
|
|---|
| 251 | for ( n = NB - 1; n >= 0; n-- ) {
|
|---|
| 252 | coeff = tb[n].coef;
|
|---|
| 253 | emn = (float) tb[n].nem;
|
|---|
| 254 | empn = (float) tb[n].nemp;
|
|---|
| 255 | dn = (float) tb[n].nd;
|
|---|
| 256 | fn = (float) tb[n].nf;
|
|---|
| 257 | theta = emn * em + empn * emp + dn * d + fn * f;
|
|---|
| 258 | v += coeff * ( (float) sin ( (double) theta ) );
|
|---|
| 259 | dv += coeff * ( (float) cos ( (double) theta ) ) *
|
|---|
| 260 | ( emn * em1 + empn * emp1 + dn * d1 + fn * f1 );
|
|---|
| 261 | }
|
|---|
| 262 | b = D2R * v;
|
|---|
| 263 | db = RATCON * dv;
|
|---|
| 264 |
|
|---|
| 265 | /* Parallax */
|
|---|
| 266 | v = 0.0f;
|
|---|
| 267 | dv = 0.0f;
|
|---|
| 268 | for ( n = NP - 1; n >= 0; n-- ) {
|
|---|
| 269 | coeff = tp[n].coef;
|
|---|
| 270 | emn = (float) tp[n].nem;
|
|---|
| 271 | empn = (float) tp[n].nemp;
|
|---|
| 272 | dn = (float) tp[n].nd;
|
|---|
| 273 | fn = (float) tp[n].nf;
|
|---|
| 274 | theta = emn * em + empn * emp + dn * d + fn * f;
|
|---|
| 275 | v += coeff * ( (float) cos ( (double) theta ) );
|
|---|
| 276 | dv += coeff * ( - (float) sin ( (double) theta ) ) *
|
|---|
| 277 | ( emn * em1 + empn * emp1 + dn * d1 + fn * f1 );
|
|---|
| 278 | }
|
|---|
| 279 | p = D2R * v;
|
|---|
| 280 | dp = RATCON * dv;
|
|---|
| 281 |
|
|---|
| 282 | /* Parallax to distance (AU, AU/sec) */
|
|---|
| 283 | sp = (float) sin ( (double) p );
|
|---|
| 284 | r = ERADAU / sp;
|
|---|
| 285 | dr = - r * dp * (float) ( cos ( (double) p ) ) / sp;
|
|---|
| 286 |
|
|---|
| 287 | /* Longitude, latitude to x, y, z (AU) */
|
|---|
| 288 | sel = (float) sin ( (double) el );
|
|---|
| 289 | cel = (float) cos ( (double) el );
|
|---|
| 290 | sb = (float) sin ( (double) b );
|
|---|
| 291 | cb = (float) cos ( (double) b );
|
|---|
| 292 | rcb = r * cb;
|
|---|
| 293 | rbd = r * db;
|
|---|
| 294 | w = rbd * sb - cb * dr;
|
|---|
| 295 | x = rcb * cel;
|
|---|
| 296 | y = rcb * sel;
|
|---|
| 297 | z = r * sb;
|
|---|
| 298 | xd = - y * del - w * cel;
|
|---|
| 299 | yd = x * del - w * sel;
|
|---|
| 300 | zd = rbd * cb + sb * dr;
|
|---|
| 301 |
|
|---|
| 302 | /* Mean obliquity */
|
|---|
| 303 | eps = D2R * ( 23.45229f - 0.00013f * t );
|
|---|
| 304 | sineps = (float) sin ( (double) eps );
|
|---|
| 305 | coseps = (float) cos ( (double) eps );
|
|---|
| 306 |
|
|---|
| 307 | /* To the equatorial system, mean of date */
|
|---|
| 308 | pv[0] = x;
|
|---|
| 309 | pv[1] = y * coseps - z * sineps;
|
|---|
| 310 | pv[2] = y * sineps + z * coseps;
|
|---|
| 311 | pv[3] = xd;
|
|---|
| 312 | pv[4] = yd * coseps - zd * sineps;
|
|---|
| 313 | pv[5] = yd * sineps + zd * coseps;
|
|---|
| 314 | }
|
|---|