1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package com.irurueta.navigation.frames;
17
18 import com.irurueta.algebra.Matrix;
19 import com.irurueta.algebra.WrongSizeException;
20 import com.irurueta.geometry.InvalidRotationMatrixException;
21 import com.irurueta.geometry.MatrixRotation3D;
22 import com.irurueta.geometry.Rotation3D;
23 import com.irurueta.navigation.geodesic.Constants;
24 import com.irurueta.units.Angle;
25 import com.irurueta.units.AngleConverter;
26 import com.irurueta.units.AngleUnit;
27 import com.irurueta.units.Time;
28 import com.irurueta.units.TimeConverter;
29 import com.irurueta.units.TimeUnit;
30
31 import java.io.Serializable;
32 import java.util.Objects;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 public class CoordinateTransformation implements Serializable, Cloneable {
49
50
51
52
53 public static final int ROWS = MatrixRotation3D.ROTATION3D_INHOM_MATRIX_ROWS;
54
55
56
57
58 public static final int COLS = MatrixRotation3D.ROTATION3D_INHOM_MATRIX_ROWS;
59
60
61
62
63 public static final double DEFAULT_THRESHOLD = 1e-11;
64
65
66
67
68 public static final double EARTH_ROTATION_RATE = Constants.EARTH_ROTATION_RATE;
69
70
71
72
73 Matrix matrix;
74
75
76
77
78 private FrameType sourceType;
79
80
81
82
83 private FrameType destinationType;
84
85
86
87
88
89
90
91
92
93 public CoordinateTransformation(final FrameType sourceType, final FrameType destinationType) {
94 try {
95 matrix = Matrix.identity(ROWS, COLS);
96 } catch (final WrongSizeException ignore) {
97
98 }
99
100 setSourceType(sourceType);
101 setDestinationType(destinationType);
102 }
103
104
105
106
107
108
109
110
111
112
113
114
115 public CoordinateTransformation(final Matrix matrix, final FrameType sourceType, final FrameType destinationType,
116 final double threshold) throws InvalidRotationMatrixException {
117 setMatrix(matrix, threshold);
118 setSourceType(sourceType);
119 setDestinationType(destinationType);
120 }
121
122
123
124
125
126
127
128
129
130
131 public CoordinateTransformation(final Matrix matrix, final FrameType sourceType, final FrameType destinationType)
132 throws InvalidRotationMatrixException {
133 this(matrix, sourceType, destinationType, DEFAULT_THRESHOLD);
134 }
135
136
137
138
139
140
141
142
143
144
145
146
147 public CoordinateTransformation(final double roll, final double pitch, final double yaw,
148 final FrameType sourceType, final FrameType destinationType) {
149 this(sourceType, destinationType);
150 setEulerAngles(roll, pitch, yaw);
151 }
152
153
154
155
156
157
158
159
160
161
162
163
164 public CoordinateTransformation(final Angle roll, final Angle pitch, final Angle yaw,
165 final FrameType sourceType, final FrameType destinationType) {
166 this(sourceType, destinationType);
167 setEulerAngles(roll, pitch, yaw);
168 }
169
170
171
172
173
174
175
176
177 public CoordinateTransformation(final Rotation3D rotation, final FrameType sourceType,
178 final FrameType destinationType) {
179 this(sourceType, destinationType);
180 fromRotation(rotation);
181 }
182
183
184
185
186
187
188 public CoordinateTransformation(final CoordinateTransformation input) {
189 this(input.sourceType, input.destinationType);
190 copyFrom(input);
191 }
192
193
194
195
196
197
198 public Matrix getMatrix() {
199 Matrix result;
200 try {
201 result = new Matrix(ROWS, COLS);
202 getMatrix(result);
203 } catch (final WrongSizeException ignore) {
204
205 result = null;
206 }
207 return result;
208 }
209
210
211
212
213
214
215 public void getMatrix(Matrix result) {
216 matrix.copyTo(result);
217 }
218
219
220
221
222
223
224
225
226
227 public void setMatrix(final Matrix matrix, final double threshold) throws InvalidRotationMatrixException {
228
229 if (!isValidMatrix(matrix, threshold)) {
230 throw new InvalidRotationMatrixException();
231 }
232
233 this.matrix = matrix;
234 }
235
236
237
238
239
240
241
242 public void setMatrix(final Matrix matrix) throws InvalidRotationMatrixException {
243 setMatrix(matrix, DEFAULT_THRESHOLD);
244 }
245
246
247
248
249
250
251
252
253
254
255 public static boolean isValidMatrix(final Matrix matrix, final double threshold) {
256 if (threshold < Rotation3D.MIN_THRESHOLD) {
257 throw new IllegalArgumentException();
258 }
259
260 return Rotation3D.isValidRotationMatrix(matrix, threshold);
261 }
262
263
264
265
266
267
268
269
270 public static boolean isValidMatrix(final Matrix matrix) {
271 return isValidMatrix(matrix, DEFAULT_THRESHOLD);
272 }
273
274
275
276
277
278
279
280
281 public double getRollEulerAngle() {
282 return Math.atan2(matrix.getElementAt(1, 2), matrix.getElementAt(2, 2));
283 }
284
285
286
287
288
289
290
291
292 public void getRollEulerAngleMeasurement(final Angle result) {
293 result.setValue(getRollEulerAngle());
294 result.setUnit(AngleUnit.RADIANS);
295 }
296
297
298
299
300
301
302
303
304 public Angle getRollEulerAngleMeasurement() {
305 final var result = new Angle(0.0, AngleUnit.RADIANS);
306 getRollEulerAngleMeasurement(result);
307 return result;
308 }
309
310
311
312
313
314
315
316
317 public double getPitchEulerAngle() {
318 return -Math.asin(matrix.getElementAt(0, 2));
319 }
320
321
322
323
324
325
326
327
328 public void getPitchEulerAngleMeasurement(final Angle result) {
329 result.setValue(getPitchEulerAngle());
330 result.setUnit(AngleUnit.RADIANS);
331 }
332
333
334
335
336
337
338
339
340 public Angle getPitchEulerAngleMeasurement() {
341 final var result = new Angle(0.0, AngleUnit.RADIANS);
342 getPitchEulerAngleMeasurement(result);
343 return result;
344 }
345
346
347
348
349
350
351
352
353 public double getYawEulerAngle() {
354 return Math.atan2(matrix.getElementAt(0, 1), matrix.getElementAt(0, 0));
355 }
356
357
358
359
360
361
362
363
364 public void getYawEulerAngleMeasurement(final Angle result) {
365 result.setValue(getYawEulerAngle());
366 result.setUnit(AngleUnit.RADIANS);
367 }
368
369
370
371
372
373
374
375
376 public Angle getYawEulerAngleMeasurement() {
377 final var result = new Angle(0.0, AngleUnit.RADIANS);
378 getYawEulerAngleMeasurement(result);
379 return result;
380 }
381
382
383
384
385
386
387
388
389
390
391 public void setEulerAngles(final double roll, final double pitch, final double yaw) {
392 final var sinPhi = Math.sin(roll);
393 final var cosPhi = Math.cos(roll);
394 final var sinTheta = Math.sin(pitch);
395 final var cosTheta = Math.cos(pitch);
396 final var sinPsi = Math.sin(yaw);
397 final var cosPsi = Math.cos(yaw);
398
399
400 matrix.setElementAt(0, 0, cosTheta * cosPsi);
401 matrix.setElementAt(0, 1, cosTheta * sinPsi);
402 matrix.setElementAt(0, 2, -sinTheta);
403
404 matrix.setElementAt(1, 0, -cosPhi * sinPsi + sinPhi * sinTheta * cosPsi);
405 matrix.setElementAt(1, 1, cosPhi * cosPsi + sinPhi * sinTheta * sinPsi);
406 matrix.setElementAt(1, 2, sinPhi * cosTheta);
407
408 matrix.setElementAt(2, 0, sinPhi * sinPsi + cosPhi * sinTheta * cosPsi);
409 matrix.setElementAt(2, 1, -sinPhi * cosPsi + cosPhi * sinTheta * sinPsi);
410 matrix.setElementAt(2, 2, cosPhi * cosTheta);
411 }
412
413
414
415
416
417
418
419
420
421
422 public void setEulerAngles(final Angle roll, final Angle pitch, final Angle yaw) {
423 setEulerAngles(AngleConverter.convert(roll.getValue().doubleValue(), roll.getUnit(), AngleUnit.RADIANS),
424 AngleConverter.convert(pitch.getValue().doubleValue(), pitch.getUnit(), AngleUnit.RADIANS),
425 AngleConverter.convert(yaw.getValue().doubleValue(), yaw.getUnit(), AngleUnit.RADIANS));
426 }
427
428
429
430
431
432
433 public FrameType getSourceType() {
434 return sourceType;
435 }
436
437
438
439
440
441
442
443 public void setSourceType(final FrameType sourceType) {
444 if (sourceType == null) {
445 throw new NullPointerException();
446 }
447
448 this.sourceType = sourceType;
449 }
450
451
452
453
454
455
456 public FrameType getDestinationType() {
457 return destinationType;
458 }
459
460
461
462
463
464
465
466 public void setDestinationType(final FrameType destinationType) {
467 if (destinationType == null) {
468 throw new NullPointerException();
469 }
470
471 this.destinationType = destinationType;
472 }
473
474
475
476
477
478
479
480 public Rotation3D asRotation() throws InvalidRotationMatrixException {
481 return new MatrixRotation3D(matrix);
482 }
483
484
485
486
487
488
489
490 public void asRotation(final Rotation3D result) throws InvalidRotationMatrixException {
491 result.fromMatrix(matrix);
492 }
493
494
495
496
497
498 public void fromRotation(final Rotation3D rotation) {
499 rotation.asInhomogeneousMatrix(matrix);
500 }
501
502
503
504
505
506
507 public void copyTo(final CoordinateTransformation output) {
508 output.sourceType = sourceType;
509 output.destinationType = destinationType;
510 matrix.copyTo(output.matrix);
511 }
512
513
514
515
516
517
518 public void copyFrom(final CoordinateTransformation input) {
519 sourceType = input.sourceType;
520 destinationType = input.destinationType;
521 matrix.copyFrom(input.matrix);
522 }
523
524
525
526
527
528
529
530 @Override
531 public int hashCode() {
532 return Objects.hash(sourceType, destinationType, matrix);
533 }
534
535
536
537
538
539
540
541
542 @Override
543 public boolean equals(final Object obj) {
544 if (obj == null) {
545 return false;
546 }
547 if (obj == this) {
548 return true;
549 }
550 if (!(obj instanceof CoordinateTransformation other)) {
551 return false;
552 }
553
554 return equals(other);
555 }
556
557
558
559
560
561
562
563 public boolean equals(final CoordinateTransformation other) {
564 return equals(other, 0.0);
565 }
566
567
568
569
570
571
572
573
574
575
576 public boolean equals(final CoordinateTransformation other, final double threshold) {
577 if (other == null) {
578 return false;
579 }
580 return other.sourceType == sourceType && other.destinationType == destinationType &&
581 other.matrix.equals(matrix, threshold);
582 }
583
584
585
586
587
588
589 public void inverse(final CoordinateTransformation result) {
590 try {
591 final var source = sourceType;
592 final var destination = destinationType;
593 final var m = Matrix.identity(ROWS, COLS);
594 m.copyFrom(this.matrix);
595
596 result.setSourceType(destination);
597 result.setDestinationType(source);
598
599
600 m.transpose();
601 result.setMatrix(m);
602 } catch (final WrongSizeException | InvalidRotationMatrixException ignore) {
603
604 }
605 }
606
607
608
609
610 public void inverse() {
611 inverse(this);
612 }
613
614
615
616
617
618
619 public CoordinateTransformation inverseAndReturnNew() {
620 final var result = new CoordinateTransformation(destinationType, sourceType);
621 inverse(result);
622 return result;
623 }
624
625
626
627
628
629
630
631
632 public static void ecefToNedMatrix(final Angle latitude, final Angle longitude, final Matrix result) {
633 ecefToNedMatrix(
634 AngleConverter.convert(latitude.getValue().doubleValue(), latitude.getUnit(), AngleUnit.RADIANS),
635 AngleConverter.convert(longitude.getValue().doubleValue(), longitude.getUnit(), AngleUnit.RADIANS),
636 result);
637 }
638
639
640
641
642
643
644
645
646 public static Matrix ecefToNedMatrix(final Angle latitude, final Angle longitude) {
647 return ecefToNedMatrix(
648 AngleConverter.convert(latitude.getValue().doubleValue(), latitude.getUnit(), AngleUnit.RADIANS),
649 AngleConverter.convert(longitude.getValue().doubleValue(), longitude.getUnit(), AngleUnit.RADIANS));
650 }
651
652
653
654
655
656
657
658
659 public static void ecefToNedMatrix(final double latitude, final double longitude, final Matrix result) {
660 if (result.getRows() != ROWS || result.getColumns() != COLS) {
661 try {
662 result.resize(ROWS, COLS);
663 } catch (final WrongSizeException ignore) {
664
665 }
666 }
667
668 final var cosLat = Math.cos(latitude);
669 final var sinLat = Math.sin(latitude);
670 final var cosLong = Math.cos(longitude);
671 final var sinLong = Math.sin(longitude);
672
673 result.setElementAtIndex(0, -sinLat * cosLong);
674 result.setElementAtIndex(1, -sinLong);
675 result.setElementAtIndex(2, -cosLat * cosLong);
676
677 result.setElementAtIndex(3, -sinLat * sinLong);
678 result.setElementAtIndex(4, cosLong);
679 result.setElementAtIndex(5, -cosLat * sinLong);
680
681 result.setElementAtIndex(6, cosLat);
682 result.setElementAtIndex(7, 0.0);
683 result.setElementAtIndex(8, -sinLat);
684 }
685
686
687
688
689
690
691
692
693 public static Matrix ecefToNedMatrix(final double latitude, final double longitude) {
694 Matrix result;
695 try {
696 result = new Matrix(CoordinateTransformation.ROWS, CoordinateTransformation.COLS);
697 ecefToNedMatrix(latitude, longitude, result);
698 } catch (final WrongSizeException ignore) {
699
700 result = null;
701 }
702 return result;
703 }
704
705
706
707
708
709
710
711
712 public static void ecefToNedCoordinateTransformationMatrix(
713 final Angle latitude, final Angle longitude, final CoordinateTransformation result) {
714 ecefToNedCoordinateTransformationMatrix(
715 AngleConverter.convert(latitude.getValue().doubleValue(), latitude.getUnit(), AngleUnit.RADIANS),
716 AngleConverter.convert(longitude.getValue().doubleValue(), longitude.getUnit(), AngleUnit.RADIANS),
717 result);
718 }
719
720
721
722
723
724
725
726
727 public static CoordinateTransformation ecefToNedCoordinateTransformationMatrix(
728 final Angle latitude, final Angle longitude) {
729 return ecefToNedCoordinateTransformationMatrix(
730 AngleConverter.convert(latitude.getValue().doubleValue(), latitude.getUnit(), AngleUnit.RADIANS),
731 AngleConverter.convert(longitude.getValue().doubleValue(), longitude.getUnit(), AngleUnit.RADIANS));
732 }
733
734
735
736
737
738
739
740
741 public static void ecefToNedCoordinateTransformationMatrix(
742 final double latitude, final double longitude, final CoordinateTransformation result) {
743 try {
744 result.setSourceType(FrameType.EARTH_CENTERED_EARTH_FIXED_FRAME);
745 result.setDestinationType(FrameType.LOCAL_NAVIGATION_FRAME);
746 result.setMatrix(ecefToNedMatrix(latitude, longitude));
747 } catch (final InvalidRotationMatrixException ignore) {
748
749 }
750 }
751
752
753
754
755
756
757
758
759 public static CoordinateTransformation ecefToNedCoordinateTransformationMatrix(
760 final double latitude, final double longitude) {
761 final var result = new CoordinateTransformation(FrameType.EARTH_CENTERED_EARTH_FIXED_FRAME,
762 FrameType.LOCAL_NAVIGATION_FRAME);
763 ecefToNedCoordinateTransformationMatrix(latitude, longitude, result);
764 return result;
765 }
766
767
768
769
770
771
772
773
774 public static void nedToEcefMatrix(final Angle latitude, final Angle longitude, final Matrix result) {
775 nedToEcefMatrix(
776 AngleConverter.convert(latitude.getValue().doubleValue(), latitude.getUnit(), AngleUnit.RADIANS),
777 AngleConverter.convert(longitude.getValue().doubleValue(), longitude.getUnit(), AngleUnit.RADIANS),
778 result);
779 }
780
781
782
783
784
785
786
787
788 public static Matrix nedToEcefMatrix(final Angle latitude, final Angle longitude) {
789 return nedToEcefMatrix(
790 AngleConverter.convert(latitude.getValue().doubleValue(), latitude.getUnit(), AngleUnit.RADIANS),
791 AngleConverter.convert(longitude.getValue().doubleValue(), longitude.getUnit(), AngleUnit.RADIANS));
792 }
793
794
795
796
797
798
799
800
801 public static void nedToEcefMatrix(final double latitude, final double longitude, final Matrix result) {
802
803
804 ecefToNedMatrix(latitude, longitude, result);
805 result.transpose();
806 }
807
808
809
810
811
812
813
814
815 public static Matrix nedToEcefMatrix(final double latitude, final double longitude) {
816 Matrix result;
817 try {
818 result = new Matrix(CoordinateTransformation.ROWS, CoordinateTransformation.COLS);
819 nedToEcefMatrix(latitude, longitude, result);
820 } catch (final WrongSizeException ignore) {
821
822 result = null;
823 }
824
825 return result;
826 }
827
828
829
830
831
832
833
834
835 public static void nedToEcefCoordinateTransformationMatrix(
836 final Angle latitude, final Angle longitude, final CoordinateTransformation result) {
837 nedToEcefCoordinateTransformationMatrix(
838 AngleConverter.convert(latitude.getValue().doubleValue(), latitude.getUnit(), AngleUnit.RADIANS),
839 AngleConverter.convert(longitude.getValue().doubleValue(), longitude.getUnit(), AngleUnit.RADIANS),
840 result);
841 }
842
843
844
845
846
847
848
849
850 public static CoordinateTransformation nedToEcefCoordinateTransformationMatrix(
851 final Angle latitude, final Angle longitude) {
852 return nedToEcefCoordinateTransformationMatrix(
853 AngleConverter.convert(latitude.getValue().doubleValue(), latitude.getUnit(), AngleUnit.RADIANS),
854 AngleConverter.convert(longitude.getValue().doubleValue(), longitude.getUnit(), AngleUnit.RADIANS));
855 }
856
857
858
859
860
861
862
863
864 public static void nedToEcefCoordinateTransformationMatrix(
865 final double latitude, final double longitude, final CoordinateTransformation result) {
866 try {
867 result.setSourceType(FrameType.LOCAL_NAVIGATION_FRAME);
868 result.setDestinationType(FrameType.EARTH_CENTERED_EARTH_FIXED_FRAME);
869 result.setMatrix(nedToEcefMatrix(latitude, longitude));
870 } catch (final InvalidRotationMatrixException ignore) {
871
872 }
873 }
874
875
876
877
878
879
880
881
882 public static CoordinateTransformation nedToEcefCoordinateTransformationMatrix(
883 final double latitude, final double longitude) {
884 final var result = new CoordinateTransformation(FrameType.LOCAL_NAVIGATION_FRAME,
885 FrameType.EARTH_CENTERED_EARTH_FIXED_FRAME);
886 nedToEcefCoordinateTransformationMatrix(latitude, longitude, result);
887 return result;
888 }
889
890
891
892
893
894
895
896
897 public static void ecefToEciMatrixFromTimeInterval(final Time timeInterval, final Matrix result) {
898 ecefToEciMatrixFromTimeInterval(TimeConverter.convert(
899 timeInterval.getValue().doubleValue(), timeInterval.getUnit(), TimeUnit.SECOND), result);
900 }
901
902
903
904
905
906
907
908
909 public static void ecefToEciMatrixFromTimeInterval(final double timeInterval, final Matrix result) {
910 ecefToEciMatrixFromAngle(EARTH_ROTATION_RATE * timeInterval, result);
911 }
912
913
914
915
916
917
918
919
920 public static void ecefToEciMatrixFromAngle(final Angle angle, final Matrix result) {
921 ecefToEciMatrixFromAngle(AngleConverter.convert(angle.getValue().doubleValue(), angle.getUnit(),
922 AngleUnit.RADIANS), result);
923 }
924
925
926
927
928
929
930
931
932 public static void ecefToEciMatrixFromAngle(final double angle, final Matrix result) {
933 if (result.getRows() != ROWS || result.getColumns() != COLS) {
934 try {
935 result.resize(ROWS, COLS);
936 } catch (final WrongSizeException ignore) {
937
938 }
939 }
940
941 final var sinAngle = Math.sin(angle);
942 final var cosAngle = Math.cos(angle);
943
944 result.setElementAt(0, 0, cosAngle);
945 result.setElementAt(0, 1, -sinAngle);
946 result.setElementAt(0, 2, 0.0);
947
948 result.setElementAt(1, 0, sinAngle);
949 result.setElementAt(1, 1, cosAngle);
950 result.setElementAt(1, 2, 0.0);
951
952 result.setElementAt(2, 0, 0.0);
953 result.setElementAt(2, 1, 0.0);
954 result.setElementAt(2, 2, 1.0);
955 }
956
957
958
959
960
961
962
963
964 public static Matrix ecefToEciMatrixFromTimeInterval(final Time timeInterval) {
965 return ecefToEciMatrixFromTimeInterval(TimeConverter.convert(
966 timeInterval.getValue().doubleValue(), timeInterval.getUnit(), TimeUnit.SECOND));
967 }
968
969
970
971
972
973
974
975
976 public static Matrix ecefToEciMatrixFromTimeInterval(final double timeInterval) {
977 return ecefToEciMatrixFromAngle(EARTH_ROTATION_RATE * timeInterval);
978 }
979
980
981
982
983
984
985
986
987 public static Matrix ecefToEciMatrixFromAngle(final Angle angle) {
988 return ecefToEciMatrixFromAngle(AngleConverter.convert(angle.getValue().doubleValue(), angle.getUnit(),
989 AngleUnit.RADIANS));
990 }
991
992
993
994
995
996
997
998
999 public static Matrix ecefToEciMatrixFromAngle(final double angle) {
1000 Matrix result;
1001 try {
1002 result = new Matrix(CoordinateTransformation.ROWS, CoordinateTransformation.COLS);
1003 ecefToEciMatrixFromAngle(angle, result);
1004 } catch (final WrongSizeException ignore) {
1005
1006 result = null;
1007 }
1008 return result;
1009 }
1010
1011
1012
1013
1014
1015
1016
1017
1018 public static void ecefToEciCoordinateTransformationMatrixFromTimeInterval(
1019 final Time timeInterval, final CoordinateTransformation result) {
1020 ecefToEciCoordinateTransformationMatrixFromTimeInterval(
1021 TimeConverter.convert(timeInterval.getValue().doubleValue(), timeInterval.getUnit(), TimeUnit.SECOND),
1022 result);
1023 }
1024
1025
1026
1027
1028
1029
1030
1031
1032 public static void ecefToEciCoordinateTransformationMatrixFromTimeInterval(
1033 final double timeInterval, final CoordinateTransformation result) {
1034 ecefToEciCoordinateTransformationMatrixFromAngle(EARTH_ROTATION_RATE * timeInterval, result);
1035 }
1036
1037
1038
1039
1040
1041
1042
1043
1044 public static void ecefToEciCoordinateTransformationMatrixFromAngle(
1045 final Angle angle, final CoordinateTransformation result) {
1046 ecefToEciCoordinateTransformationMatrixFromAngle(
1047 AngleConverter.convert(angle.getValue().doubleValue(), angle.getUnit(), AngleUnit.RADIANS), result);
1048 }
1049
1050
1051
1052
1053
1054
1055
1056
1057 public static void ecefToEciCoordinateTransformationMatrixFromAngle(
1058 final double angle, final CoordinateTransformation result) {
1059 try {
1060 result.setSourceType(FrameType.EARTH_CENTERED_EARTH_FIXED_FRAME);
1061 result.setDestinationType(FrameType.EARTH_CENTERED_INERTIAL_FRAME);
1062 result.setMatrix(ecefToEciMatrixFromAngle(angle));
1063 } catch (final InvalidRotationMatrixException ignore) {
1064
1065 }
1066 }
1067
1068
1069
1070
1071
1072
1073
1074
1075 public static CoordinateTransformation ecefToEciCoordinateTransformationMatrixFromTimeInterval(
1076 final Time timeInterval) {
1077 final var result = new CoordinateTransformation(
1078 FrameType.EARTH_CENTERED_EARTH_FIXED_FRAME, FrameType.EARTH_CENTERED_INERTIAL_FRAME);
1079 ecefToEciCoordinateTransformationMatrixFromTimeInterval(timeInterval, result);
1080 return result;
1081 }
1082
1083
1084
1085
1086
1087
1088
1089
1090 public static CoordinateTransformation ecefToEciCoordinateTransformationMatrixFromTimeInterval(
1091 final double timeInterval) {
1092 final var result = new CoordinateTransformation(
1093 FrameType.EARTH_CENTERED_EARTH_FIXED_FRAME, FrameType.EARTH_CENTERED_INERTIAL_FRAME);
1094 ecefToEciCoordinateTransformationMatrixFromTimeInterval(timeInterval, result);
1095 return result;
1096 }
1097
1098
1099
1100
1101
1102
1103
1104 public static CoordinateTransformation ecefToEciCoordinateTransformationMatrixFromAngle(final Angle angle) {
1105 final var result = new CoordinateTransformation(
1106 FrameType.EARTH_CENTERED_EARTH_FIXED_FRAME, FrameType.EARTH_CENTERED_INERTIAL_FRAME);
1107 ecefToEciCoordinateTransformationMatrixFromAngle(angle, result);
1108 return result;
1109 }
1110
1111
1112
1113
1114
1115
1116
1117 public static CoordinateTransformation ecefToEciCoordinateTransformationMatrixFromAngle(final double angle) {
1118 final var result = new CoordinateTransformation(
1119 FrameType.EARTH_CENTERED_EARTH_FIXED_FRAME, FrameType.EARTH_CENTERED_INERTIAL_FRAME);
1120 ecefToEciCoordinateTransformationMatrixFromAngle(angle, result);
1121 return result;
1122 }
1123
1124
1125
1126
1127
1128
1129
1130
1131 public static void eciToEcefMatrixFromTimeInterval(final Time timeInterval, final Matrix result) {
1132 eciToEcefMatrixFromTimeInterval(TimeConverter.convert(
1133 timeInterval.getValue().doubleValue(), timeInterval.getUnit(), TimeUnit.SECOND), result);
1134 }
1135
1136
1137
1138
1139
1140
1141
1142
1143 public static void eciToEcefMatrixFromTimeInterval(final double timeInterval, final Matrix result) {
1144 eciToEcefMatrixFromAngle(EARTH_ROTATION_RATE * timeInterval, result);
1145 }
1146
1147
1148
1149
1150
1151
1152
1153
1154 public static void eciToEcefMatrixFromAngle(final Angle angle, final Matrix result) {
1155 eciToEcefMatrixFromAngle(AngleConverter.convert(angle.getValue().doubleValue(), angle.getUnit(),
1156 AngleUnit.RADIANS), result);
1157 }
1158
1159
1160
1161
1162
1163
1164
1165
1166 public static void eciToEcefMatrixFromAngle(final double angle, final Matrix result) {
1167 if (result.getRows() != ROWS || result.getColumns() != COLS) {
1168 try {
1169 result.resize(ROWS, COLS);
1170 } catch (final WrongSizeException ignore) {
1171
1172 }
1173 }
1174
1175 final var sinAngle = Math.sin(angle);
1176 final var cosAngle = Math.cos(angle);
1177
1178 result.setElementAt(0, 0, cosAngle);
1179 result.setElementAt(0, 1, sinAngle);
1180 result.setElementAt(0, 2, 0.0);
1181
1182 result.setElementAt(1, 0, -sinAngle);
1183 result.setElementAt(1, 1, cosAngle);
1184 result.setElementAt(1, 2, 0.0);
1185
1186 result.setElementAt(2, 0, 0.0);
1187 result.setElementAt(2, 1, 0.0);
1188 result.setElementAt(2, 2, 1.0);
1189 }
1190
1191
1192
1193
1194
1195
1196
1197
1198 public static Matrix eciToEcefMatrixFromTimeInterval(final Time timeInterval) {
1199 return eciToEcefMatrixFromTimeInterval(TimeConverter.convert(
1200 timeInterval.getValue().doubleValue(), timeInterval.getUnit(), TimeUnit.SECOND));
1201 }
1202
1203
1204
1205
1206
1207
1208
1209
1210 public static Matrix eciToEcefMatrixFromTimeInterval(final double timeInterval) {
1211 return eciToEcefMatrixFromAngle(EARTH_ROTATION_RATE * timeInterval);
1212 }
1213
1214
1215
1216
1217
1218
1219
1220
1221 public static Matrix eciToEcefMatrixFromAngle(final Angle angle) {
1222 return eciToEcefMatrixFromAngle(AngleConverter.convert(
1223 angle.getValue().doubleValue(), angle.getUnit(), AngleUnit.RADIANS));
1224 }
1225
1226
1227
1228
1229
1230
1231
1232
1233 public static Matrix eciToEcefMatrixFromAngle(final double angle) {
1234 Matrix result;
1235 try {
1236 result = new Matrix(CoordinateTransformation.ROWS, CoordinateTransformation.COLS);
1237 eciToEcefMatrixFromAngle(angle, result);
1238 } catch (final WrongSizeException ignore) {
1239
1240 result = null;
1241 }
1242 return result;
1243 }
1244
1245
1246
1247
1248
1249
1250
1251
1252 public static void eciToEcefCoordinateTransformationMatrixFromTimeInterval(
1253 final Time timeInterval, final CoordinateTransformation result) {
1254 eciToEcefCoordinateTransformationMatrixFromTimeInterval(
1255 TimeConverter.convert(timeInterval.getValue().doubleValue(), timeInterval.getUnit(), TimeUnit.SECOND),
1256 result);
1257 }
1258
1259
1260
1261
1262
1263
1264
1265
1266 public static void eciToEcefCoordinateTransformationMatrixFromTimeInterval(
1267 final double timeInterval, final CoordinateTransformation result) {
1268 eciToEcefCoordinateTransformationMatrixFromAngle(EARTH_ROTATION_RATE * timeInterval, result);
1269 }
1270
1271
1272
1273
1274
1275
1276
1277
1278 public static void eciToEcefCoordinateTransformationMatrixFromAngle(
1279 final Angle angle, final CoordinateTransformation result) {
1280 eciToEcefCoordinateTransformationMatrixFromAngle(
1281 AngleConverter.convert(angle.getValue().doubleValue(), angle.getUnit(), AngleUnit.RADIANS), result);
1282 }
1283
1284
1285
1286
1287
1288
1289
1290
1291 public static void eciToEcefCoordinateTransformationMatrixFromAngle(
1292 final double angle, final CoordinateTransformation result) {
1293 try {
1294 result.setSourceType(FrameType.EARTH_CENTERED_INERTIAL_FRAME);
1295 result.setDestinationType(FrameType.EARTH_CENTERED_EARTH_FIXED_FRAME);
1296 result.setMatrix(eciToEcefMatrixFromAngle(angle));
1297 } catch (final InvalidRotationMatrixException ignore) {
1298
1299 }
1300 }
1301
1302
1303
1304
1305
1306
1307
1308
1309 public static CoordinateTransformation eciToEcefCoordinateTransformationMatrixFromTimeInterval(
1310 final Time timeInterval) {
1311 final var result = new CoordinateTransformation(
1312 FrameType.EARTH_CENTERED_INERTIAL_FRAME, FrameType.EARTH_CENTERED_EARTH_FIXED_FRAME);
1313 eciToEcefCoordinateTransformationMatrixFromTimeInterval(timeInterval, result);
1314 return result;
1315 }
1316
1317
1318
1319
1320
1321
1322
1323
1324 public static CoordinateTransformation eciToEcefCoordinateTransformationMatrixFromInterval(
1325 final double timeInterval) {
1326 final var result = new CoordinateTransformation(
1327 FrameType.EARTH_CENTERED_INERTIAL_FRAME, FrameType.EARTH_CENTERED_EARTH_FIXED_FRAME);
1328 eciToEcefCoordinateTransformationMatrixFromTimeInterval(timeInterval, result);
1329 return result;
1330 }
1331
1332
1333
1334
1335
1336
1337
1338
1339 public static CoordinateTransformation eciToEcefCoordinateTransformationMatrixFromAngle(
1340 final Angle angle) {
1341 final var result = new CoordinateTransformation(
1342 FrameType.EARTH_CENTERED_INERTIAL_FRAME, FrameType.EARTH_CENTERED_EARTH_FIXED_FRAME);
1343 eciToEcefCoordinateTransformationMatrixFromAngle(angle, result);
1344 return result;
1345 }
1346
1347
1348
1349
1350
1351
1352
1353
1354 public static CoordinateTransformation eciToEcefCoordinateTransformationMatrixFromAngle(
1355 final double angle) {
1356 final var result = new CoordinateTransformation(
1357 FrameType.EARTH_CENTERED_INERTIAL_FRAME, FrameType.EARTH_CENTERED_EARTH_FIXED_FRAME);
1358 eciToEcefCoordinateTransformationMatrixFromAngle(angle, result);
1359 return result;
1360 }
1361
1362
1363
1364
1365
1366
1367
1368 @Override
1369 protected Object clone() throws CloneNotSupportedException {
1370 final var result = (CoordinateTransformation) super.clone();
1371 copyTo(result);
1372 return result;
1373 }
1374 }