1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.frames;
18
19 import java.io.Serializable;
20
21 import org.hipparchus.RealFieldElement;
22 import org.hipparchus.geometry.euclidean.threed.FieldRotation;
23 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
24 import org.hipparchus.geometry.euclidean.threed.Rotation;
25 import org.hipparchus.geometry.euclidean.threed.Vector3D;
26 import org.hipparchus.util.FastMath;
27 import org.orekit.errors.OrekitException;
28 import org.orekit.errors.OrekitInternalError;
29 import org.orekit.time.AbsoluteDate;
30 import org.orekit.time.FieldAbsoluteDate;
31 import org.orekit.time.TimeVectorFunction;
32
33
34
35
36
37
38
39
40
41
42
43
44 class CIRFProvider implements EOPBasedTransformProvider {
45
46
47 private static final long serialVersionUID = 20130806L;
48
49
50 private final transient TimeVectorFunction xysPxy2Function;
51
52
53 private final EOPHistory eopHistory;
54
55
56
57
58
59
60
61 CIRFProvider(final EOPHistory eopHistory)
62 throws OrekitException {
63
64
65 xysPxy2Function = eopHistory.getConventions().getXYSpXY2Function();
66
67
68 this.eopHistory = eopHistory;
69
70 }
71
72
73 @Override
74 public EOPHistory getEOPHistory() {
75 return eopHistory;
76 }
77
78
79 @Override
80 public CIRFProvider getNonInterpolatingProvider()
81 throws OrekitException {
82 return new CIRFProvider(eopHistory.getNonInterpolatingEOPHistory());
83 }
84
85
86 @Override
87 public Transform getTransform(final AbsoluteDate date) throws OrekitException {
88
89 final double[] xys = xysPxy2Function.value(date);
90 final double[] dxdy = eopHistory.getNonRotatinOriginNutationCorrection(date);
91
92
93 final double xCurrent = xys[0] + dxdy[0];
94 final double yCurrent = xys[1] + dxdy[1];
95
96
97 final double sCurrent = xys[2] - xCurrent * yCurrent / 2;
98
99
100 final double x2Py2 = xCurrent * xCurrent + yCurrent * yCurrent;
101 final double zP1 = 1 + FastMath.sqrt(1 - x2Py2);
102 final double r = FastMath.sqrt(x2Py2);
103 final double sPe2 = 0.5 * (sCurrent + FastMath.atan2(yCurrent, xCurrent));
104 final double cos = FastMath.cos(sPe2);
105 final double sin = FastMath.sin(sPe2);
106 final double xPr = xCurrent + r;
107 final double xPrCos = xPr * cos;
108 final double xPrSin = xPr * sin;
109 final double yCos = yCurrent * cos;
110 final double ySin = yCurrent * sin;
111 final Rotation bpn = new Rotation(zP1 * (xPrCos + ySin), -r * (yCos + xPrSin),
112 r * (xPrCos - ySin), zP1 * (yCos - xPrSin),
113 true);
114
115 return new Transform(date, bpn, Vector3D.ZERO);
116
117 }
118
119
120 @Override
121 public <T extends RealFieldElement<T>> FieldTransform<T> getTransform(final FieldAbsoluteDate<T> date)
122 throws OrekitException {
123
124 final T[] xys = xysPxy2Function.value(date);
125 final T[] dxdy = eopHistory.getNonRotatinOriginNutationCorrection(date);
126
127
128 final T xCurrent = xys[0].add(dxdy[0]);
129 final T yCurrent = xys[1].add(dxdy[1]);
130
131
132 final T sCurrent = xys[2].subtract(xCurrent.multiply(yCurrent).multiply(0.5));
133
134
135 final T x2Py2 = xCurrent.multiply(xCurrent).add(yCurrent.multiply(yCurrent));
136 final T zP1 = x2Py2.subtract(1).negate().sqrt().add(1);
137 final T r = x2Py2.sqrt();
138 final T sPe2 = sCurrent.add(yCurrent.atan2(xCurrent)).multiply(0.5);
139 final T cos = sPe2.cos();
140 final T sin = sPe2.sin();
141 final T xPr = xCurrent.add(r);
142 final T xPrCos = xPr.multiply(cos);
143 final T xPrSin = xPr.multiply(sin);
144 final T yCos = yCurrent.multiply(cos);
145 final T ySin = yCurrent.multiply(sin);
146 final FieldRotation<T> bpn = new FieldRotation<>(zP1.multiply(xPrCos.add(ySin)),
147 r.multiply(yCos.add(xPrSin)).negate(),
148 r.multiply(xPrCos.subtract(ySin)),
149 zP1.multiply(yCos.subtract(xPrSin)),
150 true);
151
152 return new FieldTransform<>(date, bpn, FieldVector3D.getZero(date.getField()));
153
154 }
155
156
157
158
159
160
161
162 private Object writeReplace() {
163 return new DataTransferObject(eopHistory);
164 }
165
166
167 private static class DataTransferObject implements Serializable {
168
169
170 private static final long serialVersionUID = 20131209L;
171
172
173 private final EOPHistory eopHistory;
174
175
176
177
178 DataTransferObject(final EOPHistory eopHistory) {
179 this.eopHistory = eopHistory;
180 }
181
182
183
184
185 private Object readResolve() {
186 try {
187
188 return new CIRFProvider(eopHistory);
189 } catch (OrekitException oe) {
190 throw new OrekitInternalError(oe);
191 }
192 }
193
194 }
195
196 }