1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.utils;
18
19 import org.hipparchus.CalculusFieldElement;
20 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
21 import org.hipparchus.geometry.euclidean.threed.Vector3D;
22 import org.hipparchus.util.FastMath;
23 import org.orekit.bodies.OneAxisEllipsoid;
24 import org.orekit.propagation.FieldSpacecraftState;
25 import org.orekit.propagation.SpacecraftState;
26
27
28
29
30
31 public class OccultationEngine {
32
33
34 private final OneAxisEllipsoid occulting;
35
36
37 private final ExtendedPVCoordinatesProvider occulted;
38
39
40 private final double occultedRadius;
41
42
43
44
45
46
47 public OccultationEngine(final ExtendedPVCoordinatesProvider occulted, final double occultedRadius,
48 final OneAxisEllipsoid occulting) {
49 this.occulted = occulted;
50 this.occultedRadius = FastMath.abs(occultedRadius);
51 this.occulting = occulting;
52 }
53
54
55
56
57 public OneAxisEllipsoid getOcculting() {
58 return occulting;
59 }
60
61
62
63
64 public ExtendedPVCoordinatesProvider getOcculted() {
65 return occulted;
66 }
67
68
69
70
71 public double getOccultedRadius() {
72 return occultedRadius;
73 }
74
75
76
77
78
79 public OccultationAngles angles(final SpacecraftState state) {
80
81 final Vector3D psat = state.getPosition(occulting.getBodyFrame());
82 final Vector3D pted = occulted.getPosition(state.getDate(), occulting.getBodyFrame());
83 final Vector3D plimb = occulting.pointOnLimb(psat, pted);
84 final Vector3D ps = psat.subtract(pted);
85 final Vector3D pi = psat.subtract(plimb);
86 final double angle = Vector3D.angle(ps, psat);
87 final double rs = FastMath.asin(occultedRadius / ps.getNorm());
88 final double ro = Vector3D.angle(pi, psat);
89 if (Double.isNaN(rs)) {
90
91
92 return new OccultationAngles(FastMath.PI, 0.0, 0.0);
93 } else {
94
95 return new OccultationAngles(angle, ro, rs);
96 }
97
98 }
99
100
101
102
103
104
105 public <T extends CalculusFieldElement<T>> FieldOccultationAngles<T> angles(final FieldSpacecraftState<T> state) {
106
107 final FieldVector3D<T> psat = state.getPosition(occulting.getBodyFrame());
108 final FieldVector3D<T> pted = occulted.getPosition(state.getDate(), occulting.getBodyFrame());
109 final FieldVector3D<T> plimb = occulting.pointOnLimb(psat, pted);
110 final FieldVector3D<T> ps = psat.subtract(pted);
111 final FieldVector3D<T> pi = psat.subtract(plimb);
112 final T angle = FieldVector3D.angle(ps, psat);
113 final T rs = FastMath.asin(ps.getNorm().reciprocal().multiply(occultedRadius));
114 final T ro = FieldVector3D.angle(pi, psat);
115 if (rs.isNaN()) {
116
117
118 final T zero = rs.getField().getZero();
119 return new FieldOccultationAngles<>(zero.newInstance(FastMath.PI), zero, zero);
120 } else {
121
122 return new FieldOccultationAngles<>(angle, ro, rs);
123 }
124
125 }
126
127
128
129
130 public static class OccultationAngles {
131
132
133 private final double separation;
134
135
136 private final double limbRadius;
137
138
139 private final double occultedApparentRadius;
140
141
142
143
144
145
146 OccultationAngles(final double separation, final double limbRadius, final double occultedApparentRadius) {
147 this.separation = separation;
148 this.limbRadius = limbRadius;
149 this.occultedApparentRadius = occultedApparentRadius;
150 }
151
152
153
154
155 public double getSeparation() {
156 return separation;
157 }
158
159
160
161
162 public double getLimbRadius() {
163 return limbRadius;
164 }
165
166
167
168
169 public double getOccultedApparentRadius() {
170 return occultedApparentRadius;
171 }
172
173 }
174
175
176
177
178
179 public static class FieldOccultationAngles<T extends CalculusFieldElement<T>> {
180
181
182 private final T separation;
183
184
185 private final T limbRadius;
186
187
188 private final T occultedApparentRadius;
189
190
191
192
193
194
195 FieldOccultationAngles(final T separation, final T limbRadius, final T occultedApparentRadius) {
196 this.separation = separation;
197 this.limbRadius = limbRadius;
198 this.occultedApparentRadius = occultedApparentRadius;
199 }
200
201
202
203
204 public T getSeparation() {
205 return separation;
206 }
207
208
209
210
211 public T getLimbRadius() {
212 return limbRadius;
213 }
214
215
216
217
218 public T getOccultedApparentRadius() {
219 return occultedApparentRadius;
220 }
221
222 }
223
224 }