1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.bodies;
18
19 import java.util.ArrayList;
20 import java.util.List;
21
22 import org.hipparchus.CalculusFieldElement;
23 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
24 import org.hipparchus.geometry.euclidean.threed.Vector3D;
25 import org.hipparchus.util.FastMath;
26 import org.hipparchus.util.FieldSinCos;
27 import org.hipparchus.util.SinCos;
28 import org.orekit.bodies.JPLEphemeridesLoader.EphemerisType;
29 import org.orekit.time.AbsoluteDate;
30 import org.orekit.time.FieldAbsoluteDate;
31 import org.orekit.time.TimeScales;
32 import org.orekit.utils.Constants;
33
34
35
36
37
38
39
40
41
42
43
44
45 abstract class PredefinedIAUPoles implements IAUPole {
46
47
48 private static final long serialVersionUID = 20200130L;
49
50
51 private final TimeScales timeScales;
52
53
54
55
56
57
58 PredefinedIAUPoles(final TimeScales timeScales) {
59 this.timeScales = timeScales;
60 }
61
62
63 private static class Sun extends PredefinedIAUPoles {
64
65
66 private static final long serialVersionUID = 20200130L;
67
68
69 private static final double W0 = 84.176;
70
71
72 private static final double W_DOT = 14.1844000;
73
74
75 private final Vector3D pole = new Vector3D(FastMath.toRadians(286.13),
76 FastMath.toRadians(63.87));
77
78
79
80
81
82
83 Sun(final TimeScales timeScales) {
84 super(timeScales);
85 }
86
87
88 public Vector3D getPole(final AbsoluteDate date) {
89 return pole;
90 }
91
92
93 public <T extends CalculusFieldElement<T>> FieldVector3D<T> getPole(final FieldAbsoluteDate<T> date) {
94 return new FieldVector3D<>(date.getField(), pole);
95 }
96
97
98 public double getPrimeMeridianAngle(final AbsoluteDate date) {
99 return FastMath.toRadians(d(date) * W_DOT + W0);
100 }
101
102
103 public <T extends CalculusFieldElement<T>> T getPrimeMeridianAngle(final FieldAbsoluteDate<T> date) {
104 return FastMath.toRadians(d(date).multiply(W_DOT).add(W0));
105 }
106
107 }
108
109
110 private static class Mercury extends PredefinedIAUPoles {
111
112
113 private static final long serialVersionUID = 20200130L;
114
115
116 private static final double ALPHA_0 = 281.0097;
117
118
119 private static final double ALPHA_DOT = -0.0328;
120
121
122 private static final double DELTA_0 = 61.4143;
123
124
125 private static final double DELTA_DOT = -0.0049;
126
127
128 private static final double W_0 = 329.5469;
129
130
131 private static final double W_DOT = 6.1385025;
132
133
134 private static final double M1_COEFF = 0.00993822;
135
136
137 private static final double M2_COEFF = -0.00104581;
138
139
140 private static final double M3_COEFF = -0.00010280;
141
142
143 private static final double M4_COEFF = -0.00002364;
144
145
146 private static final double M5_COEFF = -0.00000532;
147
148
149 private static final double M1_0 = 174.791086;
150
151
152 private static final double M1_DOT = 4.092335;
153
154
155 private static final double M2_0 = 349.582171;
156
157
158 private static final double M2_DOT = 8.184670;
159
160
161 private static final double M3_0 = 164.373257;
162
163
164 private static final double M3_DOT = 12.277005;
165
166
167 private static final double M4_0 = 339.164343;
168
169
170 private static final double M4_DOT = 16.369340;
171
172
173 private static final double M5_0 = 153.955429;
174
175
176 private static final double M5_DOT = 20.461675;
177
178
179
180
181
182
183 Mercury(final TimeScales timeScales) {
184 super(timeScales);
185 }
186
187
188 public Vector3D getPole(final AbsoluteDate date) {
189 final double t = t(date);
190 return new Vector3D(FastMath.toRadians(t * ALPHA_DOT + ALPHA_0),
191 FastMath.toRadians(t * DELTA_DOT + DELTA_0));
192 }
193
194
195 public <T extends CalculusFieldElement<T>> FieldVector3D<T> getPole(final FieldAbsoluteDate<T> date) {
196 final T t = t(date);
197 return new FieldVector3D<>(FastMath.toRadians(t.multiply(ALPHA_DOT).add(ALPHA_0)),
198 FastMath.toRadians(t.multiply(DELTA_DOT).add(DELTA_0)));
199 }
200
201
202 public double getPrimeMeridianAngle(final AbsoluteDate date) {
203 final double d = d(date);
204 return FastMath.toRadians(d(date) * W_DOT + W_0 +
205 FastMath.sin(FastMath.toRadians(d * M1_DOT + M1_0)) * M1_COEFF +
206 FastMath.sin(FastMath.toRadians(d * M2_DOT + M2_0)) * M2_COEFF +
207 FastMath.sin(FastMath.toRadians(d * M3_DOT + M3_0)) * M3_COEFF +
208 FastMath.sin(FastMath.toRadians(d * M4_DOT + M4_0)) * M4_COEFF +
209 FastMath.sin(FastMath.toRadians(d * M5_DOT + M5_0)) * M5_COEFF);
210 }
211
212
213 public <T extends CalculusFieldElement<T>> T getPrimeMeridianAngle(final FieldAbsoluteDate<T> date) {
214 final T d = d(date);
215 return FastMath.toRadians(d(date).multiply(W_DOT).add(W_0).
216 add(FastMath.toRadians(d.multiply(M1_DOT).add(M1_0)).sin().multiply(M1_COEFF)).
217 add(FastMath.toRadians(d.multiply(M2_DOT).add(M2_0)).sin().multiply(M2_COEFF)).
218 add(FastMath.toRadians(d.multiply(M3_DOT).add(M3_0)).sin().multiply(M3_COEFF)).
219 add(FastMath.toRadians(d.multiply(M4_DOT).add(M4_0)).sin().multiply(M4_COEFF)).
220 add(FastMath.toRadians(d.multiply(M5_DOT).add(M5_0)).sin().multiply(M5_COEFF)));
221 }
222
223 }
224
225
226 private static class Venus extends PredefinedIAUPoles {
227
228
229 private static final long serialVersionUID = 20200130L;
230
231
232 private static final double W_0 = 160.20;
233
234
235 private static final double W_DOT = -1.4813688;
236
237
238 private final Vector3D pole = new Vector3D(FastMath.toRadians(272.76),
239 FastMath.toRadians(67.16));
240
241
242
243
244
245
246 Venus(final TimeScales timeScales) {
247 super(timeScales);
248 }
249
250
251 public Vector3D getPole(final AbsoluteDate date) {
252 return pole;
253 }
254
255
256 public <T extends CalculusFieldElement<T>> FieldVector3D<T> getPole(final FieldAbsoluteDate<T> date) {
257 return new FieldVector3D<>(date.getField(), pole);
258 }
259
260
261 public double getPrimeMeridianAngle(final AbsoluteDate date) {
262 return FastMath.toRadians(d(date) * W_DOT + W_0);
263 }
264
265
266 public <T extends CalculusFieldElement<T>> T getPrimeMeridianAngle(final FieldAbsoluteDate<T> date) {
267 return FastMath.toRadians(d(date).multiply(W_DOT).add(W_0));
268 }
269
270 }
271
272
273 private static class Earth extends PredefinedIAUPoles {
274
275
276 private static final long serialVersionUID = 20200130L;
277
278
279 private static final double ALPHA_0 = 0.00;
280
281
282 private static final double ALPHA_DOT = -0.641;
283
284
285 private static final double DELTA_0 = 90.00;
286
287
288 private static final double DELTA_DOT = -0.557;
289
290
291 private static final double W_0 = 190.147;
292
293
294 private static final double W_DOT = 360.9856235;
295
296
297
298
299
300
301 Earth(final TimeScales timeScales) {
302 super(timeScales);
303 }
304
305
306 public Vector3D getPole(final AbsoluteDate date) {
307 final double t = t(date);
308 return new Vector3D(FastMath.toRadians(t * ALPHA_DOT + ALPHA_0),
309 FastMath.toRadians(t * DELTA_DOT + DELTA_0));
310 }
311
312
313 public <T extends CalculusFieldElement<T>> FieldVector3D<T> getPole(final FieldAbsoluteDate<T> date) {
314 final T t = t(date);
315 return new FieldVector3D<>(FastMath.toRadians(t.multiply(ALPHA_DOT).add(ALPHA_0)),
316 FastMath.toRadians(t.multiply(DELTA_DOT).add(DELTA_0)));
317 }
318
319
320 @Override
321 public Vector3D getNode(final AbsoluteDate date) {
322 final double t = t(date);
323 return new Vector3D(FastMath.toRadians(t * ALPHA_DOT + ALPHA_0 + 90.0),
324 0.0);
325 }
326
327
328 @Override
329 public <T extends CalculusFieldElement<T>> FieldVector3D<T> getNode(final FieldAbsoluteDate<T> date) {
330 final T t = t(date);
331 return new FieldVector3D<>(FastMath.toRadians(t.multiply(ALPHA_DOT).add(ALPHA_0 + 90.0)),
332 date.getField().getZero());
333 }
334
335
336 public double getPrimeMeridianAngle(final AbsoluteDate date) {
337 return FastMath.toRadians(d(date) * W_DOT + W_0);
338 }
339
340
341 public <T extends CalculusFieldElement<T>> T getPrimeMeridianAngle(final FieldAbsoluteDate<T> date) {
342 return FastMath.toRadians(d(date).multiply(W_DOT).add(W_0));
343 }
344
345 }
346
347
348 private static class Moon extends PredefinedIAUPoles {
349
350
351 private static final long serialVersionUID = 20200130L;
352
353
354 private static final double ALPHA_0 = 269.9949;
355
356
357 private static final double ALPHA_DOT = 0.0031;
358
359
360 private static final double DELTA_0 = 66.5392;
361
362
363 private static final double DELTA_DOT = 0.0130;
364
365
366 private static final double W_0 = 38.3213;
367
368
369 private static final double W_DOT = 13.17635815;
370
371
372 private static final double W_DOT_DOT = -1.4e-12;
373
374
375 private static final double E01_0 = 125.045;
376
377
378 private static final double E01_DOT = -0.0529921;
379
380
381 private static final double E01_SIN = -3.8787;
382
383
384 private static final double E01_COS = 1.5419;
385
386
387 private static final double E01_W_SIN = 3.5610;
388
389
390 private static final double E02_0 = 250.089;
391
392
393 private static final double E02_DOT = -0.1059842;
394
395
396 private static final double E02_SIN = -0.1204;
397
398
399 private static final double E02_COS = 0.0239;
400
401
402 private static final double E02_W_SIN = 0.1208;
403
404
405 private static final double E03_0 = 260.008;
406
407
408 private static final double E03_DOT = 13.0120009;
409
410
411 private static final double E03_SIN = 0.0700;
412
413
414 private static final double E03_COS = -0.0278;
415
416
417 private static final double E03_W_SIN = -0.0642;
418
419
420 private static final double E04_0 = 176.625;
421
422
423 private static final double E04_DOT = 13.3407154;
424
425
426 private static final double E04_SIN = -0.0172;
427
428
429 private static final double E04_COS = 0.0068;
430
431
432 private static final double E04_W_SIN = 0.0158;
433
434
435 private static final double E05_0 = 357.529;
436
437
438 private static final double E05_DOT = 0.9856003;
439
440
441 private static final double E05_W_SIN = 0.0252;
442
443
444 private static final double E06_0 = 311.589;
445
446
447 private static final double E06_DOT = 26.4057084;
448
449
450 private static final double E06_SIN = 0.0072;
451
452
453 private static final double E06_COS = -0.0029;
454
455
456 private static final double E06_W_SIN = -0.0066;
457
458
459 private static final double E07_0 = 134.963;
460
461
462 private static final double E07_DOT = 13.0649930;
463
464
465 private static final double E07_COS = 0.0009;
466
467
468 private static final double E07_W_SIN = -0.0047;
469
470
471 private static final double E08_0 = 276.617;
472
473
474 private static final double E08_DOT = 0.3287146;
475
476
477 private static final double E08_W_SIN = -0.0046;
478
479
480 private static final double E09_0 = 34.226;
481
482
483 private static final double E09_DOT = 1.7484877;
484
485
486 private static final double E09_W_SIN = 0.0028;
487
488
489 private static final double E10_0 = 15.134;
490
491
492 private static final double E10_DOT = -0.1589763;
493
494
495 private static final double E10_SIN = -0.0052;
496
497
498 private static final double E10_COS = 0.0008;
499
500
501 private static final double E10_W_SIN = 0.0052;
502
503
504 private static final double E11_0 = 119.743;
505
506
507 private static final double E11_DOT = 0.0036096;
508
509
510 private static final double E11_W_SIN = 0.0040;
511
512
513 private static final double E12_0 = 239.961;
514
515
516 private static final double E12_DOT = 0.1643573;
517
518
519 private static final double E12_W_SIN = 0.0019;
520
521
522 private static final double E13_0 = 25.053;
523
524
525 private static final double E13_DOT = 12.9590088;
526
527
528 private static final double E13_SIN = 0.0043;
529
530
531 private static final double E13_COS = -0.0009;
532
533
534 private static final double E13_W_SIN = -0.0044;
535
536
537
538
539
540
541 Moon(final TimeScales timeScales) {
542 super(timeScales);
543 }
544
545
546 public Vector3D getPole(final AbsoluteDate date) {
547 final double d = d(date);
548 final double t = t(date);
549
550 final SinCos scE01 = FastMath.sinCos(FastMath.toRadians(d * E01_DOT + E01_0));
551 final SinCos scE02 = FastMath.sinCos(FastMath.toRadians(d * E02_DOT + E02_0));
552 final SinCos scE03 = FastMath.sinCos(FastMath.toRadians(d * E03_DOT + E03_0));
553 final SinCos scE04 = FastMath.sinCos(FastMath.toRadians(d * E04_DOT + E04_0));
554 final SinCos scE06 = FastMath.sinCos(FastMath.toRadians(d * E06_DOT + E06_0));
555 final SinCos scE10 = FastMath.sinCos(FastMath.toRadians(d * E10_DOT + E10_0));
556 final SinCos scE13 = FastMath.sinCos(FastMath.toRadians(d * E13_DOT + E13_0));
557
558 return new Vector3D(FastMath.toRadians(t * ALPHA_DOT + ALPHA_0 +
559 scE01.sin() * E01_SIN +
560 scE02.sin() * E02_SIN +
561 scE03.sin() * E03_SIN +
562 scE04.sin() * E04_SIN +
563 scE06.sin() * E06_SIN +
564 scE10.sin() * E10_SIN +
565 scE13.sin() * E13_SIN),
566 FastMath.toRadians(t * DELTA_DOT + DELTA_0 +
567 scE01.cos() * E01_COS +
568 scE02.cos() * E02_COS +
569 scE03.cos() * E03_COS +
570 scE04.cos() * E04_COS +
571 scE06.cos() * E06_COS +
572 FastMath.cos(FastMath.toRadians(d * E07_DOT + E07_0)) * E07_COS +
573 scE10.cos() * E10_COS +
574 scE13.cos() * E13_COS));
575 }
576
577
578 public <T extends CalculusFieldElement<T>> FieldVector3D<T> getPole(final FieldAbsoluteDate<T> date) {
579 final T d = d(date);
580 final T t = t(date);
581
582 final FieldSinCos<T> scE01 = FastMath.sinCos(FastMath.toRadians(d.multiply(E01_DOT).add(E01_0)));
583 final FieldSinCos<T> scE02 = FastMath.sinCos(FastMath.toRadians(d.multiply(E02_DOT).add(E02_0)));
584 final FieldSinCos<T> scE03 = FastMath.sinCos(FastMath.toRadians(d.multiply(E03_DOT).add(E03_0)));
585 final FieldSinCos<T> scE04 = FastMath.sinCos(FastMath.toRadians(d.multiply(E04_DOT).add(E04_0)));
586 final FieldSinCos<T> scE06 = FastMath.sinCos(FastMath.toRadians(d.multiply(E06_DOT).add(E06_0)));
587 final FieldSinCos<T> scE10 = FastMath.sinCos(FastMath.toRadians(d.multiply(E10_DOT).add(E10_0)));
588 final FieldSinCos<T> scE13 = FastMath.sinCos(FastMath.toRadians(d.multiply(E13_DOT).add(E13_0)));
589
590 return new FieldVector3D<>(FastMath.toRadians(t.multiply(ALPHA_DOT).add(ALPHA_0).
591 add(scE01.sin().multiply(E01_SIN)).
592 add(scE02.sin().multiply(E02_SIN)).
593 add(scE03.sin().multiply(E03_SIN)).
594 add(scE04.sin().multiply(E04_SIN)).
595 add(scE06.sin().multiply(E06_SIN)).
596 add(scE10.sin().multiply(E10_SIN)).
597 add(scE13.sin().multiply(E13_SIN))),
598 FastMath.toRadians(t.multiply(DELTA_DOT).add(DELTA_0).
599 add(scE01.cos().multiply(E01_COS)).
600 add(scE02.cos().multiply(E02_COS)).
601 add(scE03.cos().multiply(E03_COS)).
602 add(scE04.cos().multiply(E04_COS)).
603 add(scE06.cos().multiply(E06_COS)).
604 add(FastMath.toRadians(d.multiply(E07_DOT).add(E07_0)).cos().multiply(E07_COS)).
605 add(scE10.cos().multiply(E10_COS)).
606 add(scE13.cos().multiply(E13_COS))));
607 }
608
609
610 public double getPrimeMeridianAngle(final AbsoluteDate date) {
611 final double d = d(date);
612
613 return FastMath.toRadians(d * (d * W_DOT_DOT + W_DOT) + W_0 +
614 FastMath.sin(FastMath.toRadians(d * E01_DOT + E01_0)) * E01_W_SIN +
615 FastMath.sin(FastMath.toRadians(d * E02_DOT + E02_0)) * E02_W_SIN +
616 FastMath.sin(FastMath.toRadians(d * E03_DOT + E03_0)) * E03_W_SIN +
617 FastMath.sin(FastMath.toRadians(d * E04_DOT + E04_0)) * E04_W_SIN +
618 FastMath.sin(FastMath.toRadians(d * E05_DOT + E05_0)) * E05_W_SIN +
619 FastMath.sin(FastMath.toRadians(d * E06_DOT + E06_0)) * E06_W_SIN +
620 FastMath.sin(FastMath.toRadians(d * E07_DOT + E07_0)) * E07_W_SIN +
621 FastMath.sin(FastMath.toRadians(d * E08_DOT + E08_0)) * E08_W_SIN +
622 FastMath.sin(FastMath.toRadians(d * E09_DOT + E09_0)) * E09_W_SIN +
623 FastMath.sin(FastMath.toRadians(d * E10_DOT + E10_0)) * E10_W_SIN +
624 FastMath.sin(FastMath.toRadians(d * E11_DOT + E11_0)) * E11_W_SIN +
625 FastMath.sin(FastMath.toRadians(d * E12_DOT + E12_0)) * E12_W_SIN +
626 FastMath.sin(FastMath.toRadians(d * E13_DOT + E13_0)) * E13_W_SIN);
627 }
628
629
630 public <T extends CalculusFieldElement<T>> T getPrimeMeridianAngle(final FieldAbsoluteDate<T> date) {
631 final T d = d(date);
632 return FastMath.toRadians(d.multiply(d.multiply(W_DOT_DOT).add(W_DOT)).add(W_0).
633 add(FastMath.toRadians(d.multiply(E01_DOT).add(E01_0)).sin().multiply(E01_W_SIN)).
634 add(FastMath.toRadians(d.multiply(E02_DOT).add(E02_0)).sin().multiply(E02_W_SIN)).
635 add(FastMath.toRadians(d.multiply(E03_DOT).add(E03_0)).sin().multiply(E03_W_SIN)).
636 add(FastMath.toRadians(d.multiply(E04_DOT).add(E04_0)).sin().multiply(E04_W_SIN)).
637 add(FastMath.toRadians(d.multiply(E05_DOT).add(E05_0)).sin().multiply(E05_W_SIN)).
638 add(FastMath.toRadians(d.multiply(E06_DOT).add(E06_0)).sin().multiply(E06_W_SIN)).
639 add(FastMath.toRadians(d.multiply(E07_DOT).add(E07_0)).sin().multiply(E07_W_SIN)).
640 add(FastMath.toRadians(d.multiply(E08_DOT).add(E08_0)).sin().multiply(E08_W_SIN)).
641 add(FastMath.toRadians(d.multiply(E09_DOT).add(E09_0)).sin().multiply(E09_W_SIN)).
642 add(FastMath.toRadians(d.multiply(E10_DOT).add(E10_0)).sin().multiply(E10_W_SIN)).
643 add(FastMath.toRadians(d.multiply(E11_DOT).add(E11_0)).sin().multiply(E11_W_SIN)).
644 add(FastMath.toRadians(d.multiply(E12_DOT).add(E12_0)).sin().multiply(E12_W_SIN)).
645 add(FastMath.toRadians(d.multiply(E13_DOT).add(E13_0)).sin().multiply(E13_W_SIN)));
646 }
647
648 }
649
650
651 private static class Mars extends PredefinedIAUPoles {
652
653
654 private static final long serialVersionUID = 20200130L;
655
656
657 private static final double ALPHA_0 = 317.68143;
658
659
660 private static final double ALPHA_DOT = -0.1061;
661
662
663 private static final double DELTA_0 = 52.88650;
664
665
666 private static final double DELTA_DOT = -0.0609;
667
668
669 private static final double W_0 = 176.630;
670
671
672 private static final double W_DOT = 350.89198226;
673
674
675
676
677
678
679 Mars(final TimeScales timeScales) {
680 super(timeScales);
681 }
682
683
684 public Vector3D getPole(final AbsoluteDate date) {
685 final double t = t(date);
686 return new Vector3D(FastMath.toRadians(t * ALPHA_DOT + ALPHA_0),
687 FastMath.toRadians(t * DELTA_DOT + DELTA_0));
688 }
689
690
691 public <T extends CalculusFieldElement<T>> FieldVector3D<T> getPole(final FieldAbsoluteDate<T> date) {
692 final T t = t(date);
693 return new FieldVector3D<>(FastMath.toRadians(t.multiply(ALPHA_DOT).add(ALPHA_0)),
694 FastMath.toRadians(t.multiply(DELTA_DOT).add(DELTA_0)));
695 }
696
697
698 public double getPrimeMeridianAngle(final AbsoluteDate date) {
699 return FastMath.toRadians(d(date) * W_DOT + W_0);
700 }
701
702
703 public <T extends CalculusFieldElement<T>> T getPrimeMeridianAngle(final FieldAbsoluteDate<T> date) {
704 return FastMath.toRadians(d(date).multiply(W_DOT).add(W_0));
705 }
706
707 }
708
709
710 private static class Jupiter extends PredefinedIAUPoles {
711
712
713 private static final long serialVersionUID = 20200130L;
714
715
716 private static final double ALPHA_0 = 268.056595;
717
718
719 private static final double ALPHA_DOT = -0.006499;
720
721
722 private static final double DELTA_0 = 64.495303;
723
724
725 private static final double DELTA_DOT = 0.002413;
726
727
728 private static final double JA_0 = 99.360714;
729
730
731 private static final double JA_DOT = 4850.4046;
732
733
734 private static final double JA_SIN = 0.000117;
735
736
737 private static final double JA_COS = 0.000050;
738
739
740 private static final double JB_0 = 175.895369;
741
742
743 private static final double JB_DOT = 1191.9605;
744
745
746 private static final double JB_SIN = 0.000938;
747
748
749 private static final double JB_COS = 0.000404;
750
751
752 private static final double JC_0 = 300.323162;
753
754
755 private static final double JC_DOT = 262.5475;
756
757
758 private static final double JC_SIN = 0.001432;
759
760
761 private static final double JC_COS = 0.000617;
762
763
764 private static final double JD_0 = 114.012305;
765
766
767 private static final double JD_DOT = 6070.2476;
768
769
770 private static final double JD_SIN = 0.000030;
771
772
773 private static final double JD_COS = -0.000013;
774
775
776 private static final double JE_0 = 49.511251;
777
778
779 private static final double JE_DOT = 64.3000;
780
781
782 private static final double JE_SIN = 0.002150;
783
784
785 private static final double JE_COS = 0.000926;
786
787
788 private static final double W_0 = 284.95;
789
790
791 private static final double W_DOT = 870.5360000;
792
793
794
795
796
797
798 Jupiter(final TimeScales timeScales) {
799 super(timeScales);
800 }
801
802
803 public Vector3D getPole(final AbsoluteDate date) {
804
805 final double t = t(date);
806 final double ja = FastMath.toRadians(t * JA_DOT + JA_0);
807 final double jb = FastMath.toRadians(t * JB_DOT + JB_0);
808 final double jc = FastMath.toRadians(t * JC_DOT + JC_0);
809 final double jd = FastMath.toRadians(t * JD_DOT + JD_0);
810 final double je = FastMath.toRadians(t * JE_DOT + JE_0);
811
812 final SinCos scJa = FastMath.sinCos(ja);
813 final SinCos scJb = FastMath.sinCos(jb);
814 final SinCos scJc = FastMath.sinCos(jc);
815 final SinCos scJd = FastMath.sinCos(jd);
816 final SinCos scJe = FastMath.sinCos(je);
817
818 return new Vector3D(FastMath.toRadians(t * ALPHA_DOT + ALPHA_0 +
819 scJa.sin() * JA_SIN +
820 scJb.sin() * JB_SIN +
821 scJc.sin() * JC_SIN +
822 scJd.sin() * JD_SIN +
823 scJe.sin() * JE_SIN),
824 FastMath.toRadians(t * DELTA_DOT + DELTA_0 +
825 scJa.cos() * JA_COS +
826 scJb.cos() * JB_COS +
827 scJc.cos() * JC_COS +
828 scJd.cos() * JD_COS +
829 scJe.cos() * JE_COS));
830 }
831
832
833 public <T extends CalculusFieldElement<T>> FieldVector3D<T> getPole(final FieldAbsoluteDate<T> date) {
834
835 final T t = t(date);
836 final T ja = FastMath.toRadians(t.multiply(JA_DOT).add(JA_0));
837 final T jb = FastMath.toRadians(t.multiply(JB_DOT).add(JB_0));
838 final T jc = FastMath.toRadians(t.multiply(JC_DOT).add(JC_0));
839 final T jd = FastMath.toRadians(t.multiply(JD_DOT).add(JD_0));
840 final T je = FastMath.toRadians(t.multiply(JE_DOT).add(JE_0));
841
842 final FieldSinCos<T> scJa = FastMath.sinCos(ja);
843 final FieldSinCos<T> scJb = FastMath.sinCos(jb);
844 final FieldSinCos<T> scJc = FastMath.sinCos(jc);
845 final FieldSinCos<T> scJd = FastMath.sinCos(jd);
846 final FieldSinCos<T> scJe = FastMath.sinCos(je);
847
848 return new FieldVector3D<>(FastMath.toRadians(t.multiply(ALPHA_DOT).add(ALPHA_0).
849 add(scJa.sin().multiply(JA_SIN)).
850 add(scJb.sin().multiply(JB_SIN)).
851 add(scJc.sin().multiply(JC_SIN)).
852 add(scJd.sin().multiply(JD_SIN)).
853 add(scJe.sin().multiply(JE_SIN))),
854 FastMath.toRadians(t.multiply(DELTA_DOT).add(DELTA_0).
855 add(scJa.cos().multiply(JA_COS)).
856 add(scJb.cos().multiply(JB_COS)).
857 add(scJc.cos().multiply(JC_COS)).
858 add(scJd.cos().multiply(JD_COS)).
859 add(scJe.cos().multiply(JE_COS))));
860
861 }
862
863
864 public double getPrimeMeridianAngle(final AbsoluteDate date) {
865 return FastMath.toRadians(d(date) * W_DOT + W_0);
866 }
867
868
869 public <T extends CalculusFieldElement<T>> T getPrimeMeridianAngle(final FieldAbsoluteDate<T> date) {
870 return FastMath.toRadians(d(date).multiply(W_DOT).add(W_0));
871 }
872
873 }
874
875
876 private static class Saturn extends PredefinedIAUPoles {
877
878
879 private static final long serialVersionUID = 20200130L;
880
881
882 private static final double ALPHA_0 = 40.589;
883
884
885 private static final double ALPHA_DOT = -0.036;
886
887
888 private static final double DELTA_0 = 83.537;
889
890
891 private static final double DELTA_DOT = -0.004;
892
893
894 private static final double W_0 = 38.90;
895
896
897 private static final double W_DOT = 810.7939024;
898
899
900
901
902
903
904 Saturn(final TimeScales timeScales) {
905 super(timeScales);
906 }
907
908
909 public Vector3D getPole(final AbsoluteDate date) {
910 final double t = t(date);
911 return new Vector3D(FastMath.toRadians(t * ALPHA_DOT + ALPHA_0),
912 FastMath.toRadians(t * DELTA_DOT + DELTA_0));
913 }
914
915
916 public <T extends CalculusFieldElement<T>> FieldVector3D<T> getPole(final FieldAbsoluteDate<T> date) {
917 final T t = t(date);
918 return new FieldVector3D<>(FastMath.toRadians(t.multiply(ALPHA_DOT).add(ALPHA_0)),
919 FastMath.toRadians(t.multiply(DELTA_DOT).add(DELTA_0)));
920 }
921
922
923 public double getPrimeMeridianAngle(final AbsoluteDate date) {
924 return FastMath.toRadians(d(date) * W_DOT + W_0);
925 }
926
927
928 public <T extends CalculusFieldElement<T>> T getPrimeMeridianAngle(final FieldAbsoluteDate<T> date) {
929 return FastMath.toRadians(d(date).multiply(W_DOT).add(W_0));
930 }
931
932 }
933
934
935 private static class Uranus extends PredefinedIAUPoles {
936
937
938 private static final long serialVersionUID = 20200130L;
939
940
941 private static final double W_0 = 203.81;
942
943
944 private static final double W_DOT = -501.1600928;
945
946
947 private final Vector3D pole = new Vector3D(FastMath.toRadians(257.311),
948 FastMath.toRadians(-15.175));
949
950
951
952
953
954
955 Uranus(final TimeScales timeScales) {
956 super(timeScales);
957 }
958
959
960 public Vector3D getPole(final AbsoluteDate date) {
961 return pole;
962 }
963
964
965 public <T extends CalculusFieldElement<T>> FieldVector3D<T> getPole(final FieldAbsoluteDate<T> date) {
966 return new FieldVector3D<>(date.getField(), pole);
967 }
968
969
970 public double getPrimeMeridianAngle(final AbsoluteDate date) {
971 return FastMath.toRadians(d(date) * W_DOT + W_0);
972 }
973
974
975 public <T extends CalculusFieldElement<T>> T getPrimeMeridianAngle(final FieldAbsoluteDate<T> date) {
976 return FastMath.toRadians(d(date).multiply(W_DOT).add(W_0));
977 }
978
979 }
980
981
982 private static class Neptune extends PredefinedIAUPoles {
983
984
985 private static final long serialVersionUID = 20200130L;
986
987
988 private static final double ALPHA_0 = 299.36;
989
990
991 private static final double ALPHA_SIN = 0.70;
992
993
994 private static final double DELTA_0 = 43.46;
995
996
997 private static final double DELTA_COS = -0.51;
998
999
1000 private static final double W_0 = 253.18;
1001
1002
1003 private static final double W_DOT = 536.3128492;
1004
1005
1006 private static final double W_SIN = -0.48;
1007
1008
1009 private static final double N_0 = 357.85;
1010
1011
1012 private static final double N_DOT = 52.316;
1013
1014
1015
1016
1017
1018
1019 Neptune(final TimeScales timeScales) {
1020 super(timeScales);
1021 }
1022
1023
1024 public Vector3D getPole(final AbsoluteDate date) {
1025 final double n = FastMath.toRadians(t(date) * N_DOT + N_0);
1026 final SinCos sc = FastMath.sinCos(n);
1027 return new Vector3D(FastMath.toRadians(sc.sin() * ALPHA_SIN + ALPHA_0),
1028 FastMath.toRadians(sc.cos() * DELTA_COS + DELTA_0));
1029 }
1030
1031
1032 public <T extends CalculusFieldElement<T>> FieldVector3D<T> getPole(final FieldAbsoluteDate<T> date) {
1033 final T n = FastMath.toRadians(t(date).multiply(N_DOT).add(N_0));
1034 final FieldSinCos<T> sc = FastMath.sinCos(n);
1035 return new FieldVector3D<>(FastMath.toRadians(sc.sin().multiply(ALPHA_SIN).add(ALPHA_0)),
1036 FastMath.toRadians(sc.cos().multiply(DELTA_COS).add(DELTA_0)));
1037 }
1038
1039
1040 public double getPrimeMeridianAngle(final AbsoluteDate date) {
1041 final double n = FastMath.toRadians(t(date) * N_DOT + N_0);
1042 return FastMath.toRadians(d(date) * W_DOT + FastMath.sin(n) * W_SIN + W_0);
1043 }
1044
1045
1046 public <T extends CalculusFieldElement<T>> T getPrimeMeridianAngle(final FieldAbsoluteDate<T> date) {
1047 final T n = FastMath.toRadians(t(date).multiply(N_DOT).add(N_0));
1048 return FastMath.toRadians(d(date).multiply(W_DOT).add(n.sin().multiply(W_SIN)).add(W_0));
1049 }
1050
1051 }
1052
1053
1054 private static class Pluto extends PredefinedIAUPoles {
1055
1056
1057 private static final long serialVersionUID = 20200130L;
1058
1059
1060 private static final double W_0 = 302.695;
1061
1062
1063 private static final double W_DOT = 56.3625225;
1064
1065
1066 private final Vector3D pole = new Vector3D(FastMath.toRadians(132.993),
1067 FastMath.toRadians(-6.163));
1068
1069
1070
1071
1072
1073
1074 Pluto(final TimeScales timeScales) {
1075 super(timeScales);
1076 }
1077
1078
1079 public Vector3D getPole(final AbsoluteDate date) {
1080 return pole;
1081 }
1082
1083
1084 public <T extends CalculusFieldElement<T>> FieldVector3D<T> getPole(final FieldAbsoluteDate<T> date) {
1085 return new FieldVector3D<>(date.getField(), pole);
1086 }
1087
1088
1089 public double getPrimeMeridianAngle(final AbsoluteDate date) {
1090 return FastMath.toRadians(d(date) * W_DOT + W_0);
1091 }
1092
1093
1094 public <T extends CalculusFieldElement<T>> T getPrimeMeridianAngle(final FieldAbsoluteDate<T> date) {
1095 return FastMath.toRadians(d(date).multiply(W_DOT).add(W_0));
1096 }
1097
1098 }
1099
1100
1101
1102
1103
1104
1105
1106
1107 private static class GcrfAligned extends PredefinedIAUPoles {
1108
1109
1110 private static final long serialVersionUID = 20200130L;
1111
1112
1113
1114
1115
1116
1117 GcrfAligned(final TimeScales timeScales) {
1118 super(timeScales);
1119 }
1120
1121
1122 public Vector3D getPole(final AbsoluteDate date) {
1123 return Vector3D.PLUS_K;
1124 }
1125
1126
1127 public <T extends CalculusFieldElement<T>> FieldVector3D<T> getPole(final FieldAbsoluteDate<T> date) {
1128 return FieldVector3D.getPlusK(date.getField());
1129 }
1130
1131
1132 @Override
1133 public Vector3D getNode(final AbsoluteDate date) {
1134 return Vector3D.PLUS_I;
1135 }
1136
1137
1138 @Override
1139 public <T extends CalculusFieldElement<T>> FieldVector3D<T> getNode(final FieldAbsoluteDate<T> date) {
1140 return FieldVector3D.getPlusI(date.getField());
1141 }
1142
1143
1144 public double getPrimeMeridianAngle(final AbsoluteDate date) {
1145 return 0;
1146 }
1147
1148
1149 public <T extends CalculusFieldElement<T>> T getPrimeMeridianAngle(final FieldAbsoluteDate<T> date) {
1150 return date.getField().getZero();
1151 }
1152
1153 }
1154
1155
1156
1157
1158
1159
1160
1161 public static PredefinedIAUPoles getIAUPole(final EphemerisType body,
1162 final TimeScales timeScales) {
1163
1164 switch (body) {
1165 case SUN :
1166 return new Sun(timeScales);
1167 case MERCURY :
1168 return new Mercury(timeScales);
1169 case VENUS :
1170 return new Venus(timeScales);
1171 case EARTH :
1172 return new Earth(timeScales);
1173 case MOON :
1174 return new Moon(timeScales);
1175 case MARS :
1176 return new Mars(timeScales);
1177 case JUPITER :
1178 return new Jupiter(timeScales);
1179 case SATURN :
1180 return new Saturn(timeScales);
1181 case URANUS :
1182 return new Uranus(timeScales);
1183 case NEPTUNE :
1184 return new Neptune(timeScales);
1185 case PLUTO :
1186 return new Pluto(timeScales);
1187 default :
1188 return new GcrfAligned(timeScales);
1189 }
1190 }
1191
1192
1193
1194
1195
1196
1197
1198 static List<PredefinedIAUPoles> values(final TimeScales timeScales) {
1199 final List<PredefinedIAUPoles> values = new ArrayList<>(12);
1200 values.add(new Sun(timeScales));
1201 values.add(new Mercury(timeScales));
1202 values.add(new Venus(timeScales));
1203 values.add(new Earth(timeScales));
1204 values.add(new Moon(timeScales));
1205 values.add(new Mars(timeScales));
1206 values.add(new Jupiter(timeScales));
1207 values.add(new Saturn(timeScales));
1208 values.add(new Uranus(timeScales));
1209 values.add(new Neptune(timeScales));
1210 values.add(new Pluto(timeScales));
1211 values.add(new GcrfAligned(timeScales));
1212 return values;
1213 }
1214
1215
1216
1217
1218
1219 protected double t(final AbsoluteDate date) {
1220 return date.offsetFrom(timeScales.getJ2000Epoch(), timeScales.getTDB()) /
1221 Constants.JULIAN_CENTURY;
1222 }
1223
1224
1225
1226
1227
1228
1229 protected <T extends CalculusFieldElement<T>> T t(final FieldAbsoluteDate<T> date) {
1230 final FieldAbsoluteDate<T> j2000Epoch =
1231 new FieldAbsoluteDate<>(date.getField(), timeScales.getJ2000Epoch());
1232 return date.offsetFrom(j2000Epoch, timeScales.getTDB()).divide(Constants.JULIAN_CENTURY);
1233 }
1234
1235
1236
1237
1238
1239 protected double d(final AbsoluteDate date) {
1240 return date.offsetFrom(timeScales.getJ2000Epoch(), timeScales.getTDB()) /
1241 Constants.JULIAN_DAY;
1242 }
1243
1244
1245
1246
1247
1248
1249 protected <T extends CalculusFieldElement<T>> T d(final FieldAbsoluteDate<T> date) {
1250 final FieldAbsoluteDate<T> j2000Epoch =
1251 new FieldAbsoluteDate<>(date.getField(), timeScales.getJ2000Epoch());
1252 return date.offsetFrom(j2000Epoch, timeScales.getTDB()).divide(Constants.JULIAN_DAY);
1253 }
1254
1255 }