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