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
//
// GENERATED FILE
//
use super::*;
use crate::SpiceContext;
use f2rust_std::*;
/// Perpendicular component of a 3-vector
///
/// Find the component of a vector that is perpendicular to a second
/// vector. All vectors are 3-dimensional.
///
/// # Brief I/O
///
/// ```text
/// VARIABLE I/O DESCRIPTION
/// -------- --- --------------------------------------------------
/// A I The vector whose orthogonal component is sought.
/// B I The vector used as the orthogonal reference.
/// P O The component of A orthogonal to B.
/// ```
///
/// # Detailed Input
///
/// ```text
/// A is a double precision, 3-dimensional vector. It the
/// vector whose component orthogonal to B is sought. (There
/// is a unique decomposition of A into a sum V + P, where V
/// is parallel to B and P is orthogonal to B. We want the
/// component P.)
///
/// B is a double precision, 3-dimensional vector. This
/// vector is the vector used as a reference for the
/// decomposition of A.
/// ```
///
/// # Detailed Output
///
/// ```text
/// P is a double precision, 3-dimensional vector containing
/// the component of A that is orthogonal to B.
/// P may overwrite either A or B.
/// ```
///
/// # Exceptions
///
/// ```text
/// Error free.
/// ```
///
/// # Particulars
///
/// ```text
/// Given and non-zero vector B and a vector A, there is a unique
/// decomposition of A as a sum V + P such that P is orthogonal
/// to B and V is parallel to B. This routine finds the vector P.
///
/// If B is a zero vector, P will be identical to A.
/// ```
///
/// # Examples
///
/// ```text
/// The following table gives sample inputs and results from calling
/// VPERP.
///
/// A B P
/// ------------------------------------------
/// (6, 6, 6) ( 2, 0, 0) (0, 6, 6)
/// (6, 6, 6) (-3, 0, 0) (0, 6, 6)
/// (6, 6, 0) ( 0, 7, 0) (6, 0, 0)
/// (6, 0, 0) ( 0, 0, 9) (6, 0, 0)
/// ```
///
/// # Literature References
///
/// ```text
/// [1] G. Thomas and R. Finney, "Calculus and Analytic Geometry,"
/// 7th Edition, Addison Wesley, 1988.
/// ```
///
/// # Author and Institution
///
/// ```text
/// N.J. Bachman (JPL)
/// J. Diaz del Rio (ODC Space)
/// W.L. Taber (JPL)
/// E.D. Wright (JPL)
/// ```
///
/// # Version
///
/// ```text
/// - SPICELIB Version 1.2.0, 16-SEP-2020 (JDR)
///
/// Added IMPLICIT NONE statement.
///
/// Edited the header to comply with NAIF standard.
///
/// - SPICELIB Version 1.1.1, 11-MAY-2010 (EDW)
///
/// Minor edit to code comments eliminating typo.
///
/// Reordered header sections to proper NAIF convention.
/// Removed Revision section, it listed a duplication of a
/// $Version section entry.
///
/// - SPICELIB Version 1.1.0, 09-SEP-2005 (NJB)
///
/// Updated to remove non-standard use of duplicate arguments
/// in VSCL call.
///
/// - SPICELIB Version 1.0.1, 10-MAR-1992 (WLT)
///
/// Comment section for permuted index source lines was added
/// following the header.
///
/// - SPICELIB Version 1.0.0, 31-JAN-1990 (WLT)
/// ```
pub fn vperp(a: &[f64; 3], b: &[f64; 3], p: &mut [f64; 3]) {
VPERP(a, b, p);
}
//$Procedure VPERP ( Perpendicular component of a 3-vector )
pub fn VPERP(A: &[f64], B: &[f64], P: &mut [f64]) {
let A = DummyArray::new(A, 1..=3);
let B = DummyArray::new(B, 1..=3);
let mut P = DummyArrayMut::new(P, 1..=3);
let mut BIGA: f64 = 0.0;
let mut BIGB: f64 = 0.0;
let mut R = StackArray::<f64, 3>::new(1..=3);
let mut T = StackArray::<f64, 3>::new(1..=3);
let mut V = StackArray::<f64, 3>::new(1..=3);
//
// Local variables
//
//
// Error free routine: no check-in.
//
BIGA = intrinsics::DMAX1(&[f64::abs(A[1]), f64::abs(A[2]), f64::abs(A[3])]);
BIGB = intrinsics::DMAX1(&[f64::abs(B[1]), f64::abs(B[2]), f64::abs(B[3])]);
//
// If A is the zero vector, just set P to zero and return.
//
if (BIGA == 0.0) {
P[1] = 0.0;
P[2] = 0.0;
P[3] = 0.0;
return;
}
//
// If B is the zero vector, then set P equal to A.
//
if (BIGB == 0.0) {
P[1] = A[1];
P[2] = A[2];
P[3] = A[3];
return;
}
T[1] = (A[1] / BIGA);
T[2] = (A[2] / BIGA);
T[3] = (A[3] / BIGA);
R[1] = (B[1] / BIGB);
R[2] = (B[2] / BIGB);
R[3] = (B[3] / BIGB);
VPROJ(T.as_slice(), R.as_slice(), V.as_slice_mut());
VSUB(T.as_slice(), V.as_slice(), P.as_slice_mut());
VSCLIP(BIGA, P.as_slice_mut());
}