swe4r 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ext/swe4r/extconf.rb +3 -0
- data/ext/swe4r/src/swemptab.c +10642 -0
- data/ext/swe4r/swe4r.c +129 -0
- data/ext/swe4r/swecl.c +4948 -0
- data/ext/swe4r/swedate.c +590 -0
- data/ext/swe4r/swedate.h +82 -0
- data/ext/swe4r/swehel.c +3445 -0
- data/ext/swe4r/swehouse.c +1727 -0
- data/ext/swe4r/swehouse.h +85 -0
- data/ext/swe4r/swejpl.c +937 -0
- data/ext/swe4r/swejpl.h +105 -0
- data/ext/swe4r/swemmoon.c +1824 -0
- data/ext/swe4r/swemplan.c +959 -0
- data/ext/swe4r/swenut2000a.h +2820 -0
- data/ext/swe4r/sweodef.h +325 -0
- data/ext/swe4r/sweph.c +6241 -0
- data/ext/swe4r/sweph.h +556 -0
- data/ext/swe4r/swephexp.h +749 -0
- data/ext/swe4r/swephlib.c +2581 -0
- data/ext/swe4r/swephlib.h +177 -0
- data/lib/swe4r.rb +2 -0
- metadata +66 -0
@@ -0,0 +1,959 @@
|
|
1
|
+
/* SWISSEPH
|
2
|
+
$Header: /home/dieter/sweph/RCS/swemplan.c,v 1.74 2008/06/16 10:07:20 dieter Exp $
|
3
|
+
Moshier planet routines
|
4
|
+
|
5
|
+
modified for SWISSEPH by Dieter Koch
|
6
|
+
|
7
|
+
**************************************************************/
|
8
|
+
/* Copyright (C) 1997 - 2008 Astrodienst AG, Switzerland. All rights reserved.
|
9
|
+
|
10
|
+
License conditions
|
11
|
+
------------------
|
12
|
+
|
13
|
+
This file is part of Swiss Ephemeris.
|
14
|
+
|
15
|
+
Swiss Ephemeris is distributed with NO WARRANTY OF ANY KIND. No author
|
16
|
+
or distributor accepts any responsibility for the consequences of using it,
|
17
|
+
or for whether it serves any particular purpose or works at all, unless he
|
18
|
+
or she says so in writing.
|
19
|
+
|
20
|
+
Swiss Ephemeris is made available by its authors under a dual licensing
|
21
|
+
system. The software developer, who uses any part of Swiss Ephemeris
|
22
|
+
in his or her software, must choose between one of the two license models,
|
23
|
+
which are
|
24
|
+
a) GNU public license version 2 or later
|
25
|
+
b) Swiss Ephemeris Professional License
|
26
|
+
|
27
|
+
The choice must be made before the software developer distributes software
|
28
|
+
containing parts of Swiss Ephemeris to others, and before any public
|
29
|
+
service using the developed software is activated.
|
30
|
+
|
31
|
+
If the developer choses the GNU GPL software license, he or she must fulfill
|
32
|
+
the conditions of that license, which includes the obligation to place his
|
33
|
+
or her whole software project under the GNU GPL or a compatible license.
|
34
|
+
See http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
35
|
+
|
36
|
+
If the developer choses the Swiss Ephemeris Professional license,
|
37
|
+
he must follow the instructions as found in http://www.astro.com/swisseph/
|
38
|
+
and purchase the Swiss Ephemeris Professional Edition from Astrodienst
|
39
|
+
and sign the corresponding license contract.
|
40
|
+
|
41
|
+
The License grants you the right to use, copy, modify and redistribute
|
42
|
+
Swiss Ephemeris, but only under certain conditions described in the License.
|
43
|
+
Among other things, the License requires that the copyright notices and
|
44
|
+
this notice be preserved on all copies.
|
45
|
+
|
46
|
+
Authors of the Swiss Ephemeris: Dieter Koch and Alois Treindl
|
47
|
+
|
48
|
+
The authors of Swiss Ephemeris have no control or influence over any of
|
49
|
+
the derived works, i.e. over software or services created by other
|
50
|
+
programmers which use Swiss Ephemeris functions.
|
51
|
+
|
52
|
+
The names of the authors or of the copyright holder (Astrodienst) must not
|
53
|
+
be used for promoting any software, product or service which uses or contains
|
54
|
+
the Swiss Ephemeris. This copyright notice is the ONLY place where the
|
55
|
+
names of the authors can legally appear, except in cases where they have
|
56
|
+
given special permission in writing.
|
57
|
+
|
58
|
+
The trademarks 'Swiss Ephemeris' and 'Swiss Ephemeris inside' may be used
|
59
|
+
for promoting such software, products or services.
|
60
|
+
*/
|
61
|
+
|
62
|
+
#include <string.h>
|
63
|
+
#include "swephexp.h"
|
64
|
+
#include "sweph.h"
|
65
|
+
#include "swephlib.h"
|
66
|
+
#include "src/swemptab.c"
|
67
|
+
|
68
|
+
#define TIMESCALE 3652500.0
|
69
|
+
|
70
|
+
#define mods3600(x) ((x) - 1.296e6 * floor ((x)/1.296e6))
|
71
|
+
|
72
|
+
#define FICT_GEO 1
|
73
|
+
#define KGAUSS_GEO 0.0000298122353216 /* Earth only */
|
74
|
+
/* #define KGAUSS_GEO 0.00002999502129737 Earth + Moon */
|
75
|
+
|
76
|
+
static void embofs_mosh(double J, double *xemb);
|
77
|
+
static int check_t_terms(double t, char *sinp, double *doutp);
|
78
|
+
|
79
|
+
static int read_elements_file(int32 ipl, double tjd,
|
80
|
+
double *tjd0, double *tequ,
|
81
|
+
double *mano, double *sema, double *ecce,
|
82
|
+
double *parg, double *node, double *incl,
|
83
|
+
char *pname, int32 *fict_ifl, char *serr);
|
84
|
+
|
85
|
+
static int pnoint2msh[] = {2, 2, 0, 1, 3, 4, 5, 6, 7, 8, };
|
86
|
+
|
87
|
+
|
88
|
+
/* From Simon et al (1994) */
|
89
|
+
static double freqs[] =
|
90
|
+
{
|
91
|
+
/* Arc sec per 10000 Julian years. */
|
92
|
+
53810162868.8982,
|
93
|
+
21066413643.3548,
|
94
|
+
12959774228.3429,
|
95
|
+
6890507749.3988,
|
96
|
+
1092566037.7991,
|
97
|
+
439960985.5372,
|
98
|
+
154248119.3933,
|
99
|
+
78655032.0744,
|
100
|
+
52272245.1795
|
101
|
+
};
|
102
|
+
|
103
|
+
static double phases[] =
|
104
|
+
{
|
105
|
+
/* Arc sec. */
|
106
|
+
252.25090552 * 3600.,
|
107
|
+
181.97980085 * 3600.,
|
108
|
+
100.46645683 * 3600.,
|
109
|
+
355.43299958 * 3600.,
|
110
|
+
34.35151874 * 3600.,
|
111
|
+
50.07744430 * 3600.,
|
112
|
+
314.05500511 * 3600.,
|
113
|
+
304.34866548 * 3600.,
|
114
|
+
860492.1546,
|
115
|
+
};
|
116
|
+
|
117
|
+
static struct plantbl *planets[] =
|
118
|
+
{
|
119
|
+
&mer404,
|
120
|
+
&ven404,
|
121
|
+
&ear404,
|
122
|
+
&mar404,
|
123
|
+
&jup404,
|
124
|
+
&sat404,
|
125
|
+
&ura404,
|
126
|
+
&nep404,
|
127
|
+
&plu404
|
128
|
+
};
|
129
|
+
|
130
|
+
static double FAR ss[9][24];
|
131
|
+
static double FAR cc[9][24];
|
132
|
+
|
133
|
+
static void sscc (int k, double arg, int n);
|
134
|
+
|
135
|
+
int swi_moshplan2 (double J, int iplm, double *pobj)
|
136
|
+
{
|
137
|
+
int i, j, k, m, k1, ip, np, nt;
|
138
|
+
signed char FAR *p;
|
139
|
+
double FAR *pl, *pb, *pr;
|
140
|
+
double su, cu, sv, cv, T;
|
141
|
+
double t, sl, sb, sr;
|
142
|
+
struct plantbl *plan = planets[iplm];
|
143
|
+
|
144
|
+
T = (J - J2000) / TIMESCALE;
|
145
|
+
/* Calculate sin( i*MM ), etc. for needed multiple angles. */
|
146
|
+
for (i = 0; i < 9; i++)
|
147
|
+
{
|
148
|
+
if ((j = plan->max_harmonic[i]) > 0)
|
149
|
+
{
|
150
|
+
sr = (mods3600 (freqs[i] * T) + phases[i]) * STR;
|
151
|
+
sscc (i, sr, j);
|
152
|
+
}
|
153
|
+
}
|
154
|
+
|
155
|
+
/* Point to start of table of arguments. */
|
156
|
+
p = plan->arg_tbl;
|
157
|
+
/* Point to tabulated cosine and sine amplitudes. */
|
158
|
+
pl = plan->lon_tbl;
|
159
|
+
pb = plan->lat_tbl;
|
160
|
+
pr = plan->rad_tbl;
|
161
|
+
sl = 0.0;
|
162
|
+
sb = 0.0;
|
163
|
+
sr = 0.0;
|
164
|
+
|
165
|
+
for (;;)
|
166
|
+
{
|
167
|
+
/* argument of sine and cosine */
|
168
|
+
/* Number of periodic arguments. */
|
169
|
+
np = *p++;
|
170
|
+
if (np < 0)
|
171
|
+
break;
|
172
|
+
if (np == 0)
|
173
|
+
{ /* It is a polynomial term. */
|
174
|
+
nt = *p++;
|
175
|
+
/* Longitude polynomial. */
|
176
|
+
cu = *pl++;
|
177
|
+
for (ip = 0; ip < nt; ip++)
|
178
|
+
{
|
179
|
+
cu = cu * T + *pl++;
|
180
|
+
}
|
181
|
+
sl += mods3600 (cu);
|
182
|
+
/* Latitude polynomial. */
|
183
|
+
cu = *pb++;
|
184
|
+
for (ip = 0; ip < nt; ip++)
|
185
|
+
{
|
186
|
+
cu = cu * T + *pb++;
|
187
|
+
}
|
188
|
+
sb += cu;
|
189
|
+
/* Radius polynomial. */
|
190
|
+
cu = *pr++;
|
191
|
+
for (ip = 0; ip < nt; ip++)
|
192
|
+
{
|
193
|
+
cu = cu * T + *pr++;
|
194
|
+
}
|
195
|
+
sr += cu;
|
196
|
+
continue;
|
197
|
+
}
|
198
|
+
k1 = 0;
|
199
|
+
cv = 0.0;
|
200
|
+
sv = 0.0;
|
201
|
+
for (ip = 0; ip < np; ip++)
|
202
|
+
{
|
203
|
+
/* What harmonic. */
|
204
|
+
j = *p++;
|
205
|
+
/* Which planet. */
|
206
|
+
m = *p++ - 1;
|
207
|
+
if (j)
|
208
|
+
{
|
209
|
+
k = j;
|
210
|
+
if (j < 0)
|
211
|
+
k = -k;
|
212
|
+
k -= 1;
|
213
|
+
su = ss[m][k]; /* sin(k*angle) */
|
214
|
+
if (j < 0)
|
215
|
+
su = -su;
|
216
|
+
cu = cc[m][k];
|
217
|
+
if (k1 == 0)
|
218
|
+
{ /* set first angle */
|
219
|
+
sv = su;
|
220
|
+
cv = cu;
|
221
|
+
k1 = 1;
|
222
|
+
}
|
223
|
+
else
|
224
|
+
{ /* combine angles */
|
225
|
+
t = su * cv + cu * sv;
|
226
|
+
cv = cu * cv - su * sv;
|
227
|
+
sv = t;
|
228
|
+
}
|
229
|
+
}
|
230
|
+
}
|
231
|
+
/* Highest power of T. */
|
232
|
+
nt = *p++;
|
233
|
+
/* Longitude. */
|
234
|
+
cu = *pl++;
|
235
|
+
su = *pl++;
|
236
|
+
for (ip = 0; ip < nt; ip++)
|
237
|
+
{
|
238
|
+
cu = cu * T + *pl++;
|
239
|
+
su = su * T + *pl++;
|
240
|
+
}
|
241
|
+
sl += cu * cv + su * sv;
|
242
|
+
/* Latitiude. */
|
243
|
+
cu = *pb++;
|
244
|
+
su = *pb++;
|
245
|
+
for (ip = 0; ip < nt; ip++)
|
246
|
+
{
|
247
|
+
cu = cu * T + *pb++;
|
248
|
+
su = su * T + *pb++;
|
249
|
+
}
|
250
|
+
sb += cu * cv + su * sv;
|
251
|
+
/* Radius. */
|
252
|
+
cu = *pr++;
|
253
|
+
su = *pr++;
|
254
|
+
for (ip = 0; ip < nt; ip++)
|
255
|
+
{
|
256
|
+
cu = cu * T + *pr++;
|
257
|
+
su = su * T + *pr++;
|
258
|
+
}
|
259
|
+
sr += cu * cv + su * sv;
|
260
|
+
}
|
261
|
+
pobj[0] = STR * sl;
|
262
|
+
pobj[1] = STR * sb;
|
263
|
+
pobj[2] = STR * plan->distance * sr + plan->distance;
|
264
|
+
return OK;
|
265
|
+
}
|
266
|
+
|
267
|
+
/* Moshier ephemeris.
|
268
|
+
* computes heliocentric cartesian equatorial coordinates of
|
269
|
+
* equinox 2000
|
270
|
+
* for earth and a planet
|
271
|
+
* tjd julian day
|
272
|
+
* ipli internal SWEPH planet number
|
273
|
+
* xp array of 6 doubles for planet's position and speed
|
274
|
+
* xe earth's
|
275
|
+
* serr error string
|
276
|
+
*/
|
277
|
+
int swi_moshplan(double tjd, int ipli, AS_BOOL do_save, double *xpret, double *xeret, char *serr)
|
278
|
+
{
|
279
|
+
int i;
|
280
|
+
int do_earth = FALSE;
|
281
|
+
double dx[3], x2[3], xxe[6], xxp[6];
|
282
|
+
double *xp, *xe;
|
283
|
+
double dt;
|
284
|
+
char s[AS_MAXCH];
|
285
|
+
int iplm = pnoint2msh[ipli];
|
286
|
+
struct plan_data *pdp = &swed.pldat[ipli];
|
287
|
+
struct plan_data *pedp = &swed.pldat[SEI_EARTH];
|
288
|
+
double seps2000 = swed.oec2000.seps;
|
289
|
+
double ceps2000 = swed.oec2000.ceps;
|
290
|
+
if (do_save) {
|
291
|
+
xp = pdp->x;
|
292
|
+
xe = pedp->x;
|
293
|
+
} else {
|
294
|
+
xp = xxp;
|
295
|
+
xe = xxe;
|
296
|
+
}
|
297
|
+
if (do_save || ipli == SEI_EARTH || xeret != NULL)
|
298
|
+
do_earth = TRUE;
|
299
|
+
/* tjd beyond ephemeris limits, give some margin for spped at edge */
|
300
|
+
if (tjd < MOSHPLEPH_START - 0.3 || tjd > MOSHPLEPH_END + 0.3) {
|
301
|
+
if (serr != NULL) {
|
302
|
+
sprintf(s, "jd %f outside Moshier planet range %.2f .. %.2f ",
|
303
|
+
tjd, MOSHPLEPH_START, MOSHPLEPH_END);
|
304
|
+
if (strlen(serr) + strlen(s) < AS_MAXCH)
|
305
|
+
strcat(serr, s);
|
306
|
+
}
|
307
|
+
return(ERR);
|
308
|
+
}
|
309
|
+
/* earth, for geocentric position */
|
310
|
+
if (do_earth) {
|
311
|
+
if (tjd == pedp->teval
|
312
|
+
&& pedp->iephe == SEFLG_MOSEPH) {
|
313
|
+
xe = pedp->x;
|
314
|
+
} else {
|
315
|
+
/* emb */
|
316
|
+
swi_moshplan2(tjd, pnoint2msh[SEI_EMB], xe); /* emb hel. ecl. 2000 polar */
|
317
|
+
swi_polcart(xe, xe); /* to cartesian */
|
318
|
+
swi_coortrf2(xe, xe, -seps2000, ceps2000);/* and equator 2000 */
|
319
|
+
embofs_mosh(tjd, xe); /* emb -> earth */
|
320
|
+
if (do_save) {
|
321
|
+
pedp->teval = tjd;
|
322
|
+
pedp->xflgs = -1;
|
323
|
+
pedp->iephe = SEFLG_MOSEPH;
|
324
|
+
}
|
325
|
+
/* one more position for speed. */
|
326
|
+
swi_moshplan2(tjd - PLAN_SPEED_INTV, pnoint2msh[SEI_EMB], x2);
|
327
|
+
swi_polcart(x2, x2);
|
328
|
+
swi_coortrf2(x2, x2, -seps2000, ceps2000);
|
329
|
+
embofs_mosh(tjd - PLAN_SPEED_INTV, x2);/**/
|
330
|
+
for (i = 0; i <= 2; i++)
|
331
|
+
dx[i] = (xe[i] - x2[i]) / PLAN_SPEED_INTV;
|
332
|
+
/* store speed */
|
333
|
+
for (i = 0; i <= 2; i++) {
|
334
|
+
xe[i+3] = dx[i];
|
335
|
+
}
|
336
|
+
}
|
337
|
+
if (xeret != NULL)
|
338
|
+
for (i = 0; i <= 5; i++)
|
339
|
+
xeret[i] = xe[i];
|
340
|
+
}
|
341
|
+
/* earth is the planet wanted */
|
342
|
+
if (ipli == SEI_EARTH) {
|
343
|
+
xp = xe;
|
344
|
+
} else {
|
345
|
+
/* other planet */
|
346
|
+
/* if planet has already been computed, return */
|
347
|
+
if (tjd == pdp->teval && pdp->iephe == SEFLG_MOSEPH) {
|
348
|
+
xp = pdp->x;
|
349
|
+
} else {
|
350
|
+
swi_moshplan2(tjd, iplm, xp);
|
351
|
+
swi_polcart(xp, xp);
|
352
|
+
swi_coortrf2(xp, xp, -seps2000, ceps2000);
|
353
|
+
if (do_save) {
|
354
|
+
pdp->teval = tjd;/**/
|
355
|
+
pdp->xflgs = -1;
|
356
|
+
pdp->iephe = SEFLG_MOSEPH;
|
357
|
+
}
|
358
|
+
/* one more position for speed.
|
359
|
+
* the following dt gives good speed for light-time correction
|
360
|
+
*/
|
361
|
+
#if 0
|
362
|
+
for (i = 0; i <= 2; i++)
|
363
|
+
dx[i] = xp[i] - pedp->x[i];
|
364
|
+
dt = LIGHTTIME_AUNIT * sqrt(square_sum(dx));
|
365
|
+
#endif
|
366
|
+
dt = PLAN_SPEED_INTV;
|
367
|
+
swi_moshplan2(tjd - dt, iplm, x2);
|
368
|
+
swi_polcart(x2, x2);
|
369
|
+
swi_coortrf2(x2, x2, -seps2000, ceps2000);
|
370
|
+
for (i = 0; i <= 2; i++)
|
371
|
+
dx[i] = (xp[i] - x2[i]) / dt;
|
372
|
+
/* store speed */
|
373
|
+
for (i = 0; i <= 2; i++) {
|
374
|
+
xp[i+3] = dx[i];
|
375
|
+
}
|
376
|
+
}
|
377
|
+
if (xpret != NULL)
|
378
|
+
for (i = 0; i <= 5; i++)
|
379
|
+
xpret[i] = xp[i];
|
380
|
+
}
|
381
|
+
return(OK);
|
382
|
+
}
|
383
|
+
|
384
|
+
|
385
|
+
/* Prepare lookup table of sin and cos ( i*Lj )
|
386
|
+
* for required multiple angles
|
387
|
+
*/
|
388
|
+
static void sscc (int k, double arg, int n)
|
389
|
+
{
|
390
|
+
double cu, su, cv, sv, s;
|
391
|
+
int i;
|
392
|
+
|
393
|
+
su = sin (arg);
|
394
|
+
cu = cos (arg);
|
395
|
+
ss[k][0] = su; /* sin(L) */
|
396
|
+
cc[k][0] = cu; /* cos(L) */
|
397
|
+
sv = 2.0 * su * cu;
|
398
|
+
cv = cu * cu - su * su;
|
399
|
+
ss[k][1] = sv; /* sin(2L) */
|
400
|
+
cc[k][1] = cv;
|
401
|
+
for (i = 2; i < n; i++)
|
402
|
+
{
|
403
|
+
s = su * cv + cu * sv;
|
404
|
+
cv = cu * cv - su * sv;
|
405
|
+
sv = s;
|
406
|
+
ss[k][i] = sv; /* sin( i+1 L ) */
|
407
|
+
cc[k][i] = cv;
|
408
|
+
}
|
409
|
+
}
|
410
|
+
|
411
|
+
|
412
|
+
/* Adjust position from Earth-Moon barycenter to Earth
|
413
|
+
*
|
414
|
+
* J = Julian day number
|
415
|
+
* xemb = rectangular equatorial coordinates of Earth
|
416
|
+
*/
|
417
|
+
static void embofs_mosh(double tjd, double *xemb)
|
418
|
+
{
|
419
|
+
double T, M, a, L, B, p;
|
420
|
+
double smp, cmp, s2mp, c2mp, s2d, c2d, sf, cf;
|
421
|
+
double s2f, sx, cx, xyz[6];
|
422
|
+
double seps = swed.oec.seps;
|
423
|
+
double ceps = swed.oec.ceps;
|
424
|
+
int i;
|
425
|
+
/* Short series for position of the Moon
|
426
|
+
*/
|
427
|
+
T = (tjd-J1900)/36525.0;
|
428
|
+
/* Mean anomaly of moon (MP) */
|
429
|
+
a = swe_degnorm(((1.44e-5*T + 0.009192)*T + 477198.8491)*T + 296.104608);
|
430
|
+
a *= DEGTORAD;
|
431
|
+
smp = sin(a);
|
432
|
+
cmp = cos(a);
|
433
|
+
s2mp = 2.0*smp*cmp; /* sin(2MP) */
|
434
|
+
c2mp = cmp*cmp - smp*smp; /* cos(2MP) */
|
435
|
+
/* Mean elongation of moon (D) */
|
436
|
+
a = swe_degnorm(((1.9e-6*T - 0.001436)*T + 445267.1142)*T + 350.737486);
|
437
|
+
a = 2.0 * DEGTORAD * a;
|
438
|
+
s2d = sin(a);
|
439
|
+
c2d = cos(a);
|
440
|
+
/* Mean distance of moon from its ascending node (F) */
|
441
|
+
a = swe_degnorm((( -3.e-7*T - 0.003211)*T + 483202.0251)*T + 11.250889);
|
442
|
+
a *= DEGTORAD;
|
443
|
+
sf = sin(a);
|
444
|
+
cf = cos(a);
|
445
|
+
s2f = 2.0*sf*cf; /* sin(2F) */
|
446
|
+
sx = s2d*cmp - c2d*smp; /* sin(2D - MP) */
|
447
|
+
cx = c2d*cmp + s2d*smp; /* cos(2D - MP) */
|
448
|
+
/* Mean longitude of moon (LP) */
|
449
|
+
L = ((1.9e-6*T - 0.001133)*T + 481267.8831)*T + 270.434164;
|
450
|
+
/* Mean anomaly of sun (M) */
|
451
|
+
M = swe_degnorm((( -3.3e-6*T - 1.50e-4)*T + 35999.0498)*T + 358.475833);
|
452
|
+
/* Ecliptic longitude of the moon */
|
453
|
+
L = L
|
454
|
+
+ 6.288750*smp
|
455
|
+
+ 1.274018*sx
|
456
|
+
+ 0.658309*s2d
|
457
|
+
+ 0.213616*s2mp
|
458
|
+
- 0.185596*sin( DEGTORAD * M )
|
459
|
+
- 0.114336*s2f;
|
460
|
+
/* Ecliptic latitude of the moon */
|
461
|
+
a = smp*cf;
|
462
|
+
sx = cmp*sf;
|
463
|
+
B = 5.128189*sf
|
464
|
+
+ 0.280606*(a+sx) /* sin(MP+F) */
|
465
|
+
+ 0.277693*(a-sx) /* sin(MP-F) */
|
466
|
+
+ 0.173238*(s2d*cf - c2d*sf); /* sin(2D-F) */
|
467
|
+
B *= DEGTORAD;
|
468
|
+
/* Parallax of the moon */
|
469
|
+
p = 0.950724
|
470
|
+
+0.051818*cmp
|
471
|
+
+0.009531*cx
|
472
|
+
+0.007843*c2d
|
473
|
+
+0.002824*c2mp;
|
474
|
+
p *= DEGTORAD;
|
475
|
+
/* Elongation of Moon from Sun
|
476
|
+
*/
|
477
|
+
L = swe_degnorm(L);
|
478
|
+
L *= DEGTORAD;
|
479
|
+
/* Distance in au */
|
480
|
+
a = 4.263523e-5/sin(p);
|
481
|
+
/* Convert to rectangular ecliptic coordinates */
|
482
|
+
xyz[0] = L;
|
483
|
+
xyz[1] = B;
|
484
|
+
xyz[2] = a;
|
485
|
+
swi_polcart(xyz, xyz);
|
486
|
+
/* Convert to equatorial */
|
487
|
+
swi_coortrf2(xyz, xyz, -seps, ceps);
|
488
|
+
/* Precess to equinox of J2000.0 */
|
489
|
+
swi_precess(xyz, tjd, J_TO_J2000);/**/
|
490
|
+
/* now emb -> earth */
|
491
|
+
for (i = 0; i <= 2; i++)
|
492
|
+
xemb[i] -= xyz[i] / (EARTH_MOON_MRAT + 1.0);
|
493
|
+
}
|
494
|
+
|
495
|
+
/* orbital elements of planets that are computed from osculating elements
|
496
|
+
* epoch
|
497
|
+
* equinox
|
498
|
+
* mean anomaly,
|
499
|
+
* semi axis,
|
500
|
+
* eccentricity,
|
501
|
+
* argument of perihelion,
|
502
|
+
* ascending node
|
503
|
+
* inclination
|
504
|
+
*/
|
505
|
+
#define SE_NEELY /* use James Neely's revised elements
|
506
|
+
* of Uranian planets*/
|
507
|
+
static char *plan_fict_nam[SE_NFICT_ELEM] =
|
508
|
+
{"Cupido", "Hades", "Zeus", "Kronos",
|
509
|
+
"Apollon", "Admetos", "Vulkanus", "Poseidon",
|
510
|
+
"Isis-Transpluto", "Nibiru", "Harrington",
|
511
|
+
"Leverrier", "Adams",
|
512
|
+
"Lowell", "Pickering",};
|
513
|
+
|
514
|
+
char *swi_get_fict_name(int32 ipl, char *snam)
|
515
|
+
{
|
516
|
+
if (read_elements_file(ipl, 0, NULL, NULL,
|
517
|
+
NULL, NULL, NULL, NULL, NULL, NULL,
|
518
|
+
snam, NULL, NULL) == ERR)
|
519
|
+
strcpy(snam, "name not found");
|
520
|
+
return snam;
|
521
|
+
}
|
522
|
+
|
523
|
+
static double plan_oscu_elem[SE_NFICT_ELEM][8] = {
|
524
|
+
#ifdef SE_NEELY
|
525
|
+
{J1900, J1900, 163.7409, 40.99837, 0.00460, 171.4333, 129.8325, 1.0833},/* Cupido Neely */
|
526
|
+
{J1900, J1900, 27.6496, 50.66744, 0.00245, 148.1796, 161.3339, 1.0500},/* Hades Neely */
|
527
|
+
{J1900, J1900, 165.1232, 59.21436, 0.00120, 299.0440, 0.0000, 0.0000},/* Zeus Neely */
|
528
|
+
{J1900, J1900, 169.0193, 64.81960, 0.00305, 208.8801, 0.0000, 0.0000},/* Kronos Neely */
|
529
|
+
{J1900, J1900, 138.0533, 70.29949, 0.00000, 0.0000, 0.0000, 0.0000},/* Apollon Neely */
|
530
|
+
{J1900, J1900, 351.3350, 73.62765, 0.00000, 0.0000, 0.0000, 0.0000},/* Admetos Neely */
|
531
|
+
{J1900, J1900, 55.8983, 77.25568, 0.00000, 0.0000, 0.0000, 0.0000},/* Vulcanus Neely */
|
532
|
+
{J1900, J1900, 165.5163, 83.66907, 0.00000, 0.0000, 0.0000, 0.0000},/* Poseidon Neely */
|
533
|
+
#else
|
534
|
+
{J1900, J1900, 104.5959, 40.99837, 0, 0, 0, 0}, /* Cupido */
|
535
|
+
{J1900, J1900, 337.4517, 50.667443, 0, 0, 0, 0}, /* Hades */
|
536
|
+
{J1900, J1900, 104.0904, 59.214362, 0, 0, 0, 0}, /* Zeus */
|
537
|
+
{J1900, J1900, 17.7346, 64.816896, 0, 0, 0, 0}, /* Kronos */
|
538
|
+
{J1900, J1900, 138.0354, 70.361652, 0, 0, 0, 0}, /* Apollon */
|
539
|
+
{J1900, J1900, -8.678, 73.736476, 0, 0, 0, 0}, /* Admetos */
|
540
|
+
{J1900, J1900, 55.9826, 77.445895, 0, 0, 0, 0}, /* Vulkanus */
|
541
|
+
{J1900, J1900, 165.3595, 83.493733, 0, 0, 0, 0}, /* Poseidon */
|
542
|
+
#endif
|
543
|
+
/* Isis-Transpluto; elements from "Die Sterne" 3/1952, p. 70ff.
|
544
|
+
* Strubell does not give an equinox. 1945 is taken to best reproduce
|
545
|
+
* ASTRON ephemeris. (This is a strange choice, though.)
|
546
|
+
* The epoch is 1772.76. The year is understood to have 366 days.
|
547
|
+
* The fraction is counted from 1 Jan. 1772 */
|
548
|
+
{2368547.66, 2431456.5, 0.0, 77.775, 0.3, 0.7, 0, 0},
|
549
|
+
/* Nibiru, elements from Christian Woeltge, Hannover */
|
550
|
+
{1856113.380954, 1856113.380954, 0.0, 234.8921, 0.981092, 103.966, -44.567, 158.708},
|
551
|
+
/* Harrington, elements from Astronomical Journal 96(4), Oct. 1988 */
|
552
|
+
{2374696.5, J2000, 0.0, 101.2, 0.411, 208.5, 275.4, 32.4},
|
553
|
+
/* Leverrier's Neptune,
|
554
|
+
according to W.G. Hoyt, "Planets X and Pluto", Tucson 1980, p. 63 */
|
555
|
+
{2395662.5, 2395662.5, 34.05, 36.15, 0.10761, 284.75, 0, 0},
|
556
|
+
/* Adam's Neptune */
|
557
|
+
{2395662.5, 2395662.5, 24.28, 37.25, 0.12062, 299.11, 0, 0},
|
558
|
+
/* Lowell's Pluto */
|
559
|
+
{2425977.5, 2425977.5, 281, 43.0, 0.202, 204.9, 0, 0},
|
560
|
+
/* Pickering's Pluto */
|
561
|
+
{2425977.5, 2425977.5, 48.95, 55.1, 0.31, 280.1, 100, 15}, /**/
|
562
|
+
#if 0 /* Ceres JPL 1600, without perturbations from other minor planets,
|
563
|
+
* from following initial elements:
|
564
|
+
* 2450600.5 2000 0 1 164.7073602 73.0340746 80.5995101
|
565
|
+
* 10.5840296 0.07652422 0.0 2.770176095 */
|
566
|
+
{2305447.5, J2000, 0.5874558977449977e+02, 0.2766536058742327e+01,
|
567
|
+
0.7870946565779195e-01, 0.5809199028919189e+02,
|
568
|
+
0.8650119410725021e+02, 0.1066835622280712e+02},
|
569
|
+
/* Chiron, Bowell database 18-mar-1997 */
|
570
|
+
{2450500.5, J2000, 7.258191, 13.67387471, 0.38174778, 339.558345, 209.379239, 6.933360}, /**/
|
571
|
+
#endif
|
572
|
+
};
|
573
|
+
|
574
|
+
/* computes a planet from osculating elements *
|
575
|
+
* tjd julian day
|
576
|
+
* ipl body number
|
577
|
+
* ipli body number in planetary data structure
|
578
|
+
* iflag flags
|
579
|
+
*/
|
580
|
+
int swi_osc_el_plan(double tjd, double *xp, int ipl, int ipli, double *xearth, double *xsun, char *serr)
|
581
|
+
{
|
582
|
+
double pqr[9], x[6];
|
583
|
+
double eps, K, fac, rho, cose, sine;
|
584
|
+
double alpha, beta, zeta, sigma, M2, Msgn, M_180_or_0;
|
585
|
+
double tjd0, tequ, mano, sema, ecce, parg, node, incl, dmot;
|
586
|
+
double cosnode, sinnode, cosincl, sinincl, cosparg, sinparg;
|
587
|
+
double M, E;
|
588
|
+
struct plan_data *pedp = &swed.pldat[SEI_EARTH];
|
589
|
+
struct plan_data *pdp = &swed.pldat[ipli];
|
590
|
+
int32 fict_ifl = 0;
|
591
|
+
int i;
|
592
|
+
/* orbital elements, either from file or, if file not found,
|
593
|
+
* from above built-in set
|
594
|
+
*/
|
595
|
+
if (read_elements_file(ipl, tjd, &tjd0, &tequ,
|
596
|
+
&mano, &sema, &ecce, &parg, &node, &incl,
|
597
|
+
NULL, &fict_ifl, serr) == ERR)
|
598
|
+
return ERR;
|
599
|
+
dmot = 0.9856076686 * DEGTORAD / sema / sqrt(sema); /* daily motion */
|
600
|
+
if (fict_ifl & FICT_GEO)
|
601
|
+
dmot /= sqrt(SUN_EARTH_MRAT);
|
602
|
+
cosnode = cos(node);
|
603
|
+
sinnode = sin(node);
|
604
|
+
cosincl = cos(incl);
|
605
|
+
sinincl = sin(incl);
|
606
|
+
cosparg = cos(parg);
|
607
|
+
sinparg = sin(parg);
|
608
|
+
/* Gaussian vector */
|
609
|
+
pqr[0] = cosparg * cosnode - sinparg * cosincl * sinnode;
|
610
|
+
pqr[1] = -sinparg * cosnode - cosparg * cosincl * sinnode;
|
611
|
+
pqr[2] = sinincl * sinnode;
|
612
|
+
pqr[3] = cosparg * sinnode + sinparg * cosincl * cosnode;
|
613
|
+
pqr[4] = -sinparg * sinnode + cosparg * cosincl * cosnode;
|
614
|
+
pqr[5] = -sinincl * cosnode;
|
615
|
+
pqr[6] = sinparg * sinincl;
|
616
|
+
pqr[7] = cosparg * sinincl;
|
617
|
+
pqr[8] = cosincl;
|
618
|
+
/* Kepler problem */
|
619
|
+
E = M = swi_mod2PI(mano + (tjd - tjd0) * dmot); /* mean anomaly of date */
|
620
|
+
/* better E for very high eccentricity and small M */
|
621
|
+
if (ecce > 0.975) {
|
622
|
+
M2 = M * RADTODEG;
|
623
|
+
if (M2 > 150 && M2 < 210) {
|
624
|
+
M2 -= 180;
|
625
|
+
M_180_or_0 = 180;
|
626
|
+
} else
|
627
|
+
M_180_or_0 = 0;
|
628
|
+
if (M2 > 330)
|
629
|
+
M2 -= 360;
|
630
|
+
if (M2 < 0) {
|
631
|
+
M2 = -M2;
|
632
|
+
Msgn = -1;
|
633
|
+
} else
|
634
|
+
Msgn = 1;
|
635
|
+
if (M2 < 30) {
|
636
|
+
M2 *= DEGTORAD;
|
637
|
+
alpha = (1 - ecce) / (4 * ecce + 0.5);
|
638
|
+
beta = M2 / (8 * ecce + 1);
|
639
|
+
zeta = pow(beta + sqrt(beta * beta + alpha * alpha), 1/3);
|
640
|
+
sigma = zeta - alpha / 2;
|
641
|
+
sigma = sigma - 0.078 * sigma * sigma * sigma * sigma * sigma / (1 + ecce);
|
642
|
+
E = Msgn * (M2 + ecce * (3 * sigma - 4 * sigma * sigma * sigma))
|
643
|
+
+ M_180_or_0;
|
644
|
+
}
|
645
|
+
}
|
646
|
+
E = swi_kepler(E, M, ecce);
|
647
|
+
/* position and speed, referred to orbital plane */
|
648
|
+
if (fict_ifl & FICT_GEO)
|
649
|
+
K = KGAUSS_GEO / sqrt(sema);
|
650
|
+
else
|
651
|
+
K = KGAUSS / sqrt(sema);
|
652
|
+
cose = cos(E);
|
653
|
+
sine = sin(E);
|
654
|
+
fac = sqrt((1 - ecce) * (1 + ecce));
|
655
|
+
rho = 1 - ecce * cose;
|
656
|
+
x[0] = sema * (cose - ecce);
|
657
|
+
x[1] = sema * fac * sine;
|
658
|
+
x[3] = -K * sine / rho;
|
659
|
+
x[4] = K * fac * cose / rho;
|
660
|
+
/* transformation to ecliptic */
|
661
|
+
xp[0] = pqr[0] * x[0] + pqr[1] * x[1];
|
662
|
+
xp[1] = pqr[3] * x[0] + pqr[4] * x[1];
|
663
|
+
xp[2] = pqr[6] * x[0] + pqr[7] * x[1];
|
664
|
+
xp[3] = pqr[0] * x[3] + pqr[1] * x[4];
|
665
|
+
xp[4] = pqr[3] * x[3] + pqr[4] * x[4];
|
666
|
+
xp[5] = pqr[6] * x[3] + pqr[7] * x[4];
|
667
|
+
/* transformation to equator */
|
668
|
+
eps = swi_epsiln(tequ);
|
669
|
+
swi_coortrf(xp, xp, -eps);
|
670
|
+
swi_coortrf(xp+3, xp+3, -eps);
|
671
|
+
/* precess to J2000 */
|
672
|
+
if (tequ != J2000) {
|
673
|
+
swi_precess(xp, tequ, J_TO_J2000);
|
674
|
+
swi_precess(xp+3, tequ, J_TO_J2000);
|
675
|
+
}
|
676
|
+
/* to solar system barycentre */
|
677
|
+
if (fict_ifl & FICT_GEO) {
|
678
|
+
for (i = 0; i <= 5; i++) {
|
679
|
+
xp[i] += xearth[i];
|
680
|
+
}
|
681
|
+
} else {
|
682
|
+
for (i = 0; i <= 5; i++) {
|
683
|
+
xp[i] += xsun[i];
|
684
|
+
}
|
685
|
+
}
|
686
|
+
if (pdp->x == xp) {
|
687
|
+
pdp->teval = tjd; /* for precession! */
|
688
|
+
pdp->iephe = pedp->iephe;
|
689
|
+
}
|
690
|
+
return OK;
|
691
|
+
}
|
692
|
+
|
693
|
+
#if 1
|
694
|
+
/* note: input parameter tjd is required for T terms in elements */
|
695
|
+
static int read_elements_file(int32 ipl, double tjd,
|
696
|
+
double *tjd0, double *tequ,
|
697
|
+
double *mano, double *sema, double *ecce,
|
698
|
+
double *parg, double *node, double *incl,
|
699
|
+
char *pname, int32 *fict_ifl, char *serr)
|
700
|
+
{
|
701
|
+
int i, iline, iplan, retc, ncpos;
|
702
|
+
FILE *fp = NULL;
|
703
|
+
char s[AS_MAXCH], *sp;
|
704
|
+
char *cpos[20], serri[AS_MAXCH];
|
705
|
+
AS_BOOL elem_found = FALSE;
|
706
|
+
double tt = 0;
|
707
|
+
/* -1, because file information is not saved, file is always closed */
|
708
|
+
if ((fp = swi_fopen(-1, SE_FICTFILE, swed.ephepath, serr)) == NULL) {
|
709
|
+
/* file does not exist, use built-in bodies */
|
710
|
+
if (ipl >= SE_NFICT_ELEM) {
|
711
|
+
if (serr != NULL)
|
712
|
+
sprintf(serr, "error no elements for fictitious body no %7.0f", (double) ipl);
|
713
|
+
return ERR;
|
714
|
+
}
|
715
|
+
if (tjd0 != NULL)
|
716
|
+
*tjd0 = plan_oscu_elem[ipl][0]; /* epoch */
|
717
|
+
if (tequ != NULL)
|
718
|
+
*tequ = plan_oscu_elem[ipl][1]; /* equinox */
|
719
|
+
if (mano != NULL)
|
720
|
+
*mano = plan_oscu_elem[ipl][2] * DEGTORAD; /* mean anomaly */
|
721
|
+
if (sema != NULL)
|
722
|
+
*sema = plan_oscu_elem[ipl][3]; /* semi-axis */
|
723
|
+
if (ecce != NULL)
|
724
|
+
*ecce = plan_oscu_elem[ipl][4]; /* eccentricity */
|
725
|
+
if (parg != NULL)
|
726
|
+
*parg = plan_oscu_elem[ipl][5] * DEGTORAD; /* arg. of peri. */
|
727
|
+
if (node != NULL)
|
728
|
+
*node = plan_oscu_elem[ipl][6] * DEGTORAD; /* asc. node */
|
729
|
+
if (incl != NULL)
|
730
|
+
*incl = plan_oscu_elem[ipl][7] * DEGTORAD; /* inclination */
|
731
|
+
if (pname != NULL)
|
732
|
+
strcpy(pname, plan_fict_nam[ipl]);
|
733
|
+
return OK;
|
734
|
+
}
|
735
|
+
/*
|
736
|
+
* find elements in file
|
737
|
+
*/
|
738
|
+
iline = 0;
|
739
|
+
iplan = -1;
|
740
|
+
while (fgets(s, AS_MAXCH, fp) != NULL) {
|
741
|
+
iline++;
|
742
|
+
sp = s;
|
743
|
+
while(*sp == ' ' || *sp == '\t')
|
744
|
+
sp++;
|
745
|
+
swi_strcpy(s, sp);
|
746
|
+
if (*s == '#')
|
747
|
+
continue;
|
748
|
+
if (*s == '\r')
|
749
|
+
continue;
|
750
|
+
if (*s == '\n')
|
751
|
+
continue;
|
752
|
+
if (*s == '\0')
|
753
|
+
continue;
|
754
|
+
if ((sp = strchr(s, '#')) != NULL)
|
755
|
+
*sp = '\0';
|
756
|
+
ncpos = swi_cutstr(s, ",", cpos, 20);
|
757
|
+
sprintf(serri, "error in file %s, line %7.0f:",
|
758
|
+
SE_FICTFILE, (double) iline);
|
759
|
+
if (ncpos < 9) {
|
760
|
+
if (serr != NULL)
|
761
|
+
sprintf(serr, "%s nine elements required", serri);
|
762
|
+
return ERR;
|
763
|
+
}
|
764
|
+
iplan++;
|
765
|
+
if (iplan != ipl)
|
766
|
+
continue;
|
767
|
+
elem_found = TRUE;
|
768
|
+
/* epoch of elements */
|
769
|
+
if (tjd0 != NULL) {
|
770
|
+
sp = cpos[0];
|
771
|
+
for (i = 0; i < 5; i++)
|
772
|
+
sp[i] = tolower(sp[i]);
|
773
|
+
if (strncmp(sp, "j2000", 5) == OK)
|
774
|
+
*tjd0 = J2000;
|
775
|
+
else if (strncmp(sp, "b1950", 5) == OK)
|
776
|
+
*tjd0 = B1950;
|
777
|
+
else if (strncmp(sp, "j1900", 5) == OK)
|
778
|
+
*tjd0 = J1900;
|
779
|
+
else if (*sp == 'j' || *sp == 'b') {
|
780
|
+
if (serr != NULL)
|
781
|
+
sprintf(serr, "%s invalid epoch", serri);
|
782
|
+
goto return_err;
|
783
|
+
} else
|
784
|
+
*tjd0 = atof(sp);
|
785
|
+
tt = tjd - *tjd0;
|
786
|
+
}
|
787
|
+
/* equinox */
|
788
|
+
if (tequ != NULL) {
|
789
|
+
sp = cpos[1];
|
790
|
+
while(*sp == ' ' || *sp == '\t')
|
791
|
+
sp++;
|
792
|
+
for (i = 0; i < 5; i++)
|
793
|
+
sp[i] = tolower(sp[i]);
|
794
|
+
if (strncmp(sp, "j2000", 5) == OK)
|
795
|
+
*tequ = J2000;
|
796
|
+
else if (strncmp(sp, "b1950", 5) == OK)
|
797
|
+
*tequ = B1950;
|
798
|
+
else if (strncmp(sp, "j1900", 5) == OK)
|
799
|
+
*tequ = J1900;
|
800
|
+
else if (strncmp(sp, "jdate", 5) == OK)
|
801
|
+
*tequ = tjd;
|
802
|
+
else if (*sp == 'j' || *sp == 'b') {
|
803
|
+
if (serr != NULL)
|
804
|
+
sprintf(serr, "%s invalid equinox", serri);
|
805
|
+
goto return_err;
|
806
|
+
} else
|
807
|
+
*tequ = atof(sp);
|
808
|
+
}
|
809
|
+
/* mean anomaly t0 */
|
810
|
+
if (mano != NULL) {
|
811
|
+
retc = check_t_terms(tt, cpos[2], mano);
|
812
|
+
*mano = swe_degnorm(*mano);
|
813
|
+
if (retc == ERR) {
|
814
|
+
if (serr != NULL)
|
815
|
+
sprintf(serr, "%s mean anomaly value invalid", serri);
|
816
|
+
goto return_err;
|
817
|
+
}
|
818
|
+
/* if mean anomaly has t terms (which happens with fictitious
|
819
|
+
* planet Vulcan), we set
|
820
|
+
* epoch = tjd, so that no motion will be added anymore
|
821
|
+
* equinox = tjd */
|
822
|
+
if (retc == 1) {
|
823
|
+
*tjd0 = tjd;
|
824
|
+
}
|
825
|
+
*mano *= DEGTORAD;
|
826
|
+
}
|
827
|
+
/* semi-axis */
|
828
|
+
if (sema != NULL) {
|
829
|
+
retc = check_t_terms(tt, cpos[3], sema);
|
830
|
+
if (*sema <= 0 || retc == ERR) {
|
831
|
+
if (serr != NULL)
|
832
|
+
sprintf(serr, "%s semi-axis value invalid", serri);
|
833
|
+
goto return_err;
|
834
|
+
}
|
835
|
+
}
|
836
|
+
/* eccentricity */
|
837
|
+
if (ecce != NULL) {
|
838
|
+
retc = check_t_terms(tt, cpos[4], ecce);
|
839
|
+
if (*ecce >= 1 || *ecce < 0 || retc == ERR) {
|
840
|
+
if (serr != NULL)
|
841
|
+
sprintf(serr, "%s eccentricity invalid (no parabolic or hyperbolic orbits allowed)", serri);
|
842
|
+
goto return_err;
|
843
|
+
}
|
844
|
+
}
|
845
|
+
/* perihelion argument */
|
846
|
+
if (parg != NULL) {
|
847
|
+
retc = check_t_terms(tt, cpos[5], parg);
|
848
|
+
*parg = swe_degnorm(*parg);
|
849
|
+
if (retc == ERR) {
|
850
|
+
if (serr != NULL)
|
851
|
+
sprintf(serr, "%s perihelion argument value invalid", serri);
|
852
|
+
goto return_err;
|
853
|
+
}
|
854
|
+
*parg *= DEGTORAD;
|
855
|
+
}
|
856
|
+
/* node */
|
857
|
+
if (node != NULL) {
|
858
|
+
retc = check_t_terms(tt, cpos[6], node);
|
859
|
+
*node = swe_degnorm(*node);
|
860
|
+
if (retc == ERR) {
|
861
|
+
if (serr != NULL)
|
862
|
+
sprintf(serr, "%s node value invalid", serri);
|
863
|
+
goto return_err;
|
864
|
+
}
|
865
|
+
*node *= DEGTORAD;
|
866
|
+
}
|
867
|
+
/* inclination */
|
868
|
+
if (incl != NULL) {
|
869
|
+
retc = check_t_terms(tt, cpos[7], incl);
|
870
|
+
*incl = swe_degnorm(*incl);
|
871
|
+
if (retc == ERR) {
|
872
|
+
if (serr != NULL)
|
873
|
+
sprintf(serr, "%s inclination value invalid", serri);
|
874
|
+
goto return_err;
|
875
|
+
}
|
876
|
+
*incl *= DEGTORAD;
|
877
|
+
}
|
878
|
+
/* planet name */
|
879
|
+
if (pname != NULL) {
|
880
|
+
sp = cpos[8];
|
881
|
+
while(*sp == ' ' || *sp == '\t')
|
882
|
+
sp++;
|
883
|
+
swi_right_trim(sp);
|
884
|
+
strcpy(pname, sp);
|
885
|
+
}
|
886
|
+
/* geocentric */
|
887
|
+
if (fict_ifl != NULL && ncpos > 9) {
|
888
|
+
for (sp = cpos[9]; *sp != '\0'; sp++)
|
889
|
+
*sp = tolower(*sp);
|
890
|
+
if (strstr(cpos[9], "geo") != NULL)
|
891
|
+
*fict_ifl |= FICT_GEO;
|
892
|
+
}
|
893
|
+
break;
|
894
|
+
}
|
895
|
+
if (!elem_found) {
|
896
|
+
if (serr != NULL)
|
897
|
+
sprintf(serr, "%s elements for planet %7.0f not found", serri, (double) ipl);
|
898
|
+
goto return_err;
|
899
|
+
}
|
900
|
+
fclose(fp);
|
901
|
+
return OK;
|
902
|
+
return_err:
|
903
|
+
fclose(fp);
|
904
|
+
return ERR;
|
905
|
+
}
|
906
|
+
#endif
|
907
|
+
|
908
|
+
static int check_t_terms(double t, char *sinp, double *doutp)
|
909
|
+
{
|
910
|
+
int i, isgn = 1, z;
|
911
|
+
int retc = 0;
|
912
|
+
char *sp;
|
913
|
+
double tt[5], fac;
|
914
|
+
tt[0] = t / 36525;
|
915
|
+
tt[1] = tt[0];
|
916
|
+
tt[2] = tt[1] * tt[1];
|
917
|
+
tt[3] = tt[2] * tt[1];
|
918
|
+
tt[4] = tt[3] * tt[1];
|
919
|
+
if ((sp = strpbrk(sinp, "+-")) != NULL)
|
920
|
+
retc = 1; /* with additional terms */
|
921
|
+
sp = sinp;
|
922
|
+
*doutp = 0;
|
923
|
+
fac = 1;
|
924
|
+
z = 0;
|
925
|
+
while (1) {
|
926
|
+
while(*sp != '\0' && strchr(" \t", *sp) != NULL)
|
927
|
+
sp++;
|
928
|
+
if (strchr("+-", *sp) || *sp == '\0') {
|
929
|
+
if (z > 0)
|
930
|
+
*doutp += fac;
|
931
|
+
isgn = 1;
|
932
|
+
if (*sp == '-')
|
933
|
+
isgn = -1;
|
934
|
+
fac = 1 * isgn;
|
935
|
+
if (*sp == '\0')
|
936
|
+
return retc;
|
937
|
+
sp++;
|
938
|
+
} else {
|
939
|
+
while(*sp != '\0' && strchr("* \t", *sp) != NULL)
|
940
|
+
sp++;
|
941
|
+
if (*sp != '\0' && strchr("tT", *sp) != NULL) {
|
942
|
+
/* a T */
|
943
|
+
sp++;
|
944
|
+
if (*sp != '\0' && strchr("+-", *sp))
|
945
|
+
fac *= tt[0];
|
946
|
+
else if ((i = atoi(sp)) <= 4 && i >= 0)
|
947
|
+
fac *= tt[i];
|
948
|
+
} else {
|
949
|
+
/* a number */
|
950
|
+
if (atof(sp) != 0 || *sp == '0')
|
951
|
+
fac *= atof(sp);
|
952
|
+
}
|
953
|
+
while (*sp != '\0' && strchr("0123456789.", *sp))
|
954
|
+
sp++;
|
955
|
+
}
|
956
|
+
z++;
|
957
|
+
}
|
958
|
+
return retc; /* there have been additional terms */
|
959
|
+
}
|