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