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 | }
|
---|