1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
//
// GENERATED FILE
//
use super::*;
use f2rust_std::*;
const XFRACT: f64 = 0.0000000001;
const KEYXFR: i32 = 1;
const SGREED: f64 = 0.00000001;
const KEYSGR: i32 = (KEYXFR + 1);
const SGPADM: f64 = 0.0000000001;
const KEYSPM: i32 = (KEYSGR + 1);
const PTMEMM: f64 = 0.0000001;
const KEYPTM: i32 = (KEYSPM + 1);
const ANGMRG: f64 = 0.000000000001;
const KEYAMG: i32 = (KEYPTM + 1);
const LONALI: f64 = 0.000000000001;
const KEYLAL: i32 = (KEYAMG + 1);
pub const NONE: i32 = 0;
pub const LONIDX: i32 = 1;
pub const LATIDX: i32 = 2;
pub const ALTIDX: i32 = 3;
const LOWER: i32 = 1;
const UPPER: i32 = 2;
const LT: i32 = -1;
const EQ: i32 = 0;
const GT: i32 = 1;
struct SaveVars {
PI2: f64,
FIRST: bool,
}
impl SaveInit for SaveVars {
fn new() -> Self {
let mut PI2: f64 = 0.0;
let mut FIRST: bool = false;
FIRST = true;
PI2 = -1.0;
Self { PI2, FIRST }
}
}
//$Procedure ZZINPDT0 ( DSK, in planetodetic element, w/o margin? )
pub fn ZZINPDT0(
P: &[f64],
LON: f64,
BOUNDS: &[f64],
CORPAR: &[f64],
EXCLUD: i32,
INSIDE: &mut bool,
ctx: &mut Context,
) -> f2rust_std::Result<()> {
let save = ctx.get_vars::<SaveVars>();
let save = &mut *save.borrow_mut();
let P = DummyArray::new(P, 1..=3);
let BOUNDS = DummyArray2D::new(BOUNDS, 1..=2, 1..=3);
let CORPAR = DummyArray::new(CORPAR, 1..);
let mut EMAX: f64 = 0.0;
let mut EMIN: f64 = 0.0;
let mut F: f64 = 0.0;
let mut LEVEL: f64 = 0.0;
let mut LOCLON: f64 = 0.0;
let mut MAXLAT: f64 = 0.0;
let mut MAXLON: f64 = 0.0;
let mut MAXALT: f64 = 0.0;
let mut MINLAT: f64 = 0.0;
let mut MINLON: f64 = 0.0;
let mut MINALT: f64 = 0.0;
let mut PMAX: f64 = 0.0;
let mut PMIN: f64 = 0.0;
let mut RE: f64 = 0.0;
let mut RP: f64 = 0.0;
let mut MAXREL: i32 = 0;
let mut MINREL: i32 = 0;
//
// SPICELIB functions
//
//
// Local parameters
//
//
// Numeric relation codes returned by ZZPDCMPL:
//
//
// Local variables
//
//
// Saved variables
//
//
// Initial values
//
if RETURN(ctx) {
return Ok(());
}
CHKIN(b"ZZINPDT0", ctx)?;
if save.FIRST {
save.PI2 = TWOPI(ctx);
save.FIRST = false;
}
//
// Unpack the shape parameters. Set the polar axis length for
// later use.
//
RE = CORPAR[1];
F = CORPAR[2];
RP = (RE * (1.0 - F));
//
// Assume the point is outside to start. This allows us
// to skip setting INSIDE when we find a boundary test
// failure.
//
*INSIDE = false;
//
// Compare coordinates of the input point and the segment
// bounds. Deal with altitude last, since it involves the
// most work. We may be able to exit before performing the
// altitude tests.
//
if (EXCLUD != LATIDX) {
//
// Compare the point's latitude to the segment's latitude bounds.
//
MINLAT = intrinsics::DMAX1(&[(BOUNDS[[LOWER, LATIDX]] - ANGMRG), -HALFPI(ctx)]);
MAXLAT = intrinsics::DMIN1(&[(BOUNDS[[UPPER, LATIDX]] + ANGMRG), HALFPI(ctx)]);
ZZPDCMPL(RE, F, P.as_slice(), MINLAT, &mut MINREL, ctx)?;
ZZPDCMPL(RE, F, P.as_slice(), MAXLAT, &mut MAXREL, ctx)?;
if FAILED(ctx) {
CHKOUT(b"ZZINPDT0", ctx)?;
return Ok(());
}
if ((MINREL == LT) || (MAXREL == GT)) {
//
// The point's latitude is outside of the segment's range.
//
CHKOUT(b"ZZINPDT0", ctx)?;
return Ok(());
}
}
//
// Move the longitude of the input point into the interval
//
// [ MINLON, MAXLON ]
//
// if necessary and if possible.
//
if (EXCLUD != LONIDX) {
//
// Put the local longitude bounds in order, if necessary.
//
ZZNRMLON(
BOUNDS[[LOWER, LONIDX]],
BOUNDS[[UPPER, LONIDX]],
ANGMRG,
&mut MINLON,
&mut MAXLON,
ctx,
)?;
//
// Compare the point's longitude to the segment's longitude
// bounds.
//
LOCLON = LON;
if (LON < (MINLON - LONALI)) {
//
// If the point's longitude is less than the segment's
// longitude by more than a small margin, shift the longitude
// right by 2*pi.
LOCLON = (LON + save.PI2);
} else if (LON > (MAXLON + LONALI)) {
//
// If the point's longitude is greater than the segment's
// longitude by more than a small margin, shift the longitude
// left by 2*pi.
LOCLON = (LON - save.PI2);
}
if ((LOCLON < (MINLON - ANGMRG)) || (LOCLON > (MAXLON + ANGMRG))) {
//
// The point's longitude, adjusted if necessary for
// comparison, is outside of the segment's range.
//
CHKOUT(b"ZZINPDT0", ctx)?;
return Ok(());
}
}
if (EXCLUD != ALTIDX) {
//
// Extract altitude bounds from the segment descriptor.
//
MINALT = BOUNDS[[LOWER, ALTIDX]];
MAXALT = BOUNDS[[UPPER, ALTIDX]];
//
// Find the semi-axes of the bounding spheroids.
//
if (F >= 0.0) {
//
// This is the oblate case. Get the semi-axis lengths
// for the inner and outer bounding spheroids.
//
ZZELLBDS(
RE, RP, MAXALT, MINALT, &mut EMAX, &mut PMAX, &mut EMIN, &mut PMIN, ctx,
)?;
} else {
//
// This is the prolate case. RP is the longer axis. Get the
// semi-axis lengths for the inner and outer bounding
// spheroids.
//
// In this call, we'll store the radii associated with
// the longer axis in PMAX and PMIN.
//
ZZELLBDS(
RP, RE, MAXALT, MINALT, &mut PMAX, &mut EMAX, &mut PMIN, &mut EMIN, ctx,
)?;
}
//
// Compute the input point's level surface parameters
// for the inner and outer bounding ellipsoids. Do these
// computations one at a time, so the second one can be
// skipped if the first one shows the point is outside
// the outer ellipsoid.
//
LEVEL = ((f64::powi((P[1] / EMAX), 2) + f64::powi((P[2] / EMAX), 2))
+ f64::powi((P[3] / PMAX), 2));
if (LEVEL > 1.0) {
//
// The point is outside of the outer bounding ellipsoid.
//
CHKOUT(b"ZZINPDT0", ctx)?;
return Ok(());
}
LEVEL = ((f64::powi((P[1] / EMIN), 2) + f64::powi((P[2] / EMIN), 2))
+ f64::powi((P[3] / PMIN), 2));
if (LEVEL < 1.0) {
//
// The point is inside the inner bounding ellipsoid, which
// implies it is outside of the segment's boundaries.
//
CHKOUT(b"ZZINPDT0", ctx)?;
return Ok(());
}
}
//
// Getting to this point means the input point is inside
// the segment. Being on the boundary counts as inside.
//
*INSIDE = true;
CHKOUT(b"ZZINPDT0", ctx)?;
Ok(())
}