Isis 3 Programmer Reference
qmini.cpp
1#include <cfloat>
2#include <cmath>
3#include <iomanip>
4
5#include "Camera.h"
6
7using namespace std;
8using namespace Isis;
9/* qmini.f -- translated by f2c (version 19980913).
10 You must link the resulting object file with the libraries:
11 -lf2c -lm (in that order)
12*/
13
14//#include "f2c.h"
15
16/* Table of constant values */
17
18static doublereal c_b2 = -1.;
19static doublereal c_b3 = 1.;
20
21/* $Procedure QMINI ( Quaternion linear interpolation ) */
22/* Subroutine */
23int qmini(doublereal *init, doublereal *final, doublereal frac, doublereal *qintrp) {
24 /* System generated locals */
25 doublereal d__1;
26
27 /* Local variables */
28 doublereal vmag, axis[3];
29 doublereal q[4], angle;
30 doublereal qscale[4];
31 doublereal intang, instar[4];
32
33 /* $ Abstract */
34
35 /* Interpolate between two quaternions using a constant angular */
36 /* rate. */
37
38 /* $ Disclaimer */
39
40 /* THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */
41 /* CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */
42 /* GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */
43 /* ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */
44 /* PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */
45 /* TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */
46 /* WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */
47 /* PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */
48 /* SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */
49 /* SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */
50
51 /* IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */
52 /* BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */
53 /* LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */
54 /* INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */
55 /* REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */
56 /* REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */
57
58 /* RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */
59 /* THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */
60 /* CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */
61 /* ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */
62
63 /* $ Required_Reading */
64
65 /* ROTATIONS */
66
67 /* $ Keywords */
68
69 /* MATH */
70 /* QUATERNION */
71 /* ROTATION */
72
73 /* $ Declarations */
74 /* $ Brief_I/O */
75
76 /* Variable I/O Description */
77 /* -------- --- -------------------------------------------------- */
78 /* INIT I Initial quaternion representing a rotation. */
79 /* FINAL I Final quaternion representing a rotation. */
80 /* FRAC I Fraction of rotation from INIT to FINAL by which */
81 /* to interpolate. */
82 /* QINTRP O Linearly interpolated quaternion. */
83
84 /* $ Detailed_Input */
85
86 /* INIT, */
87 /* FINAL, */
88 /* FRAC are, respectively, two unit quaternions between */
89 /* which to interpolate, and an interpolation */
90 /* fraction. See the Detailed_Output and Particulars */
91 /* sections for details. */
92
93 /* $ Detailed_Output */
94
95 /* QINTRP is the quaternion resulting from linear */
96 /* interpolation between INIT and FINAL by the */
97 /* fraction FRAC. By "linear interpolation" we mean */
98 /* the following: */
99
100 /* We view INIT and FINAL as quaternions */
101 /* representing two values of a time-varying */
102 /* rotation quaternion R(t) that rotates at a */
103 /* constant angular velocity (that is, the row */
104 /* vectors of R(t) rotate with constant angular */
105 /* velocity). We can say that */
106
107 /* INIT represents R(t0) */
108 /* FINAL represents R(t1) */
109
110 /* Equivalently, the SPICELIB routine Q2M maps */
111 /* INIT and FINAL to rotation matrices */
112 /* corresponding to R(t0) and R(t1) respectively. */
113
114 /* "Linear interpolation by the fraction FRAC" */
115 /* means that we evaluate R(t) at time */
116
117 /* t0 + FRAC * (t1 - t0). */
118
119
120 /* $ Parameters */
121
122 /* None. */
123
124 /* $ Exceptions */
125
126 /* 1) If either of INIT or FINAL is not a unit quaternion, the error */
127 /* SPICE(NOTAROTATION) is signaled. */
128
129 /* 2) This routine assumes that the rotation that maps INIT to FINAL */
130 /* has a rotation angle THETA radians, where */
131
132 /* 0 < THETA < pi. */
133 /* _ */
134
135 /* This routine cannot distinguish between rotations of THETA */
136 /* radians, where THETA is in the interval [0, pi), and */
137 /* rotations of */
138
139 /* THETA + 2 * k * pi */
140
141 /* radians, where k is any integer. These "large" rotations will */
142 /* yield invalid results when interpolated. You must ensure */
143 /* that the inputs you provide to this routine will not be */
144 /* subject to this sort of ambiguity. If in fact you are */
145 /* interpolating a time-depedent rotation with constant angular */
146 /* velocity AV between times t0 and t1, you must ensure that */
147
148 /* || AV || * |t1 - t0| < pi. */
149
150 /* Here we assume that the magnitude of AV is the angular rate */
151 /* of the rotation in units of radians per second. */
152
153
154 /* 3) When FRAC is outside of the interval [0, 1], the process */
155 /* performed is "extrapolation", not interpolation. Such */
156 /* values of FRAC are permitted. */
157
158 /* $ Files */
159
160 /* None. */
161
162 /* $ Particulars */
163
164 /* In the discussion below, we assume that the conditions specified */
165 /* in item (2) of the Exceptions section have been satisfied. */
166
167 /* As we've said, we view INIT and FINAL as quaternions representing */
168 /* two values of a time-varying rotation matrix R(t) that rotates at */
169 /* a constant angular velocity; we define R(t), t0, and t1 so that */
170
171 /* INIT represents R(t0) */
172 /* FINAL represents R(t1). */
173
174 /* The output quaternion QINTRP represents R(t) evaluated at the */
175 /* time */
176
177 /* t0 + FRAC * (t1 - t0). */
178
179 /* How do we evaluate R at times between t0 and t1? Since the row */
180 /* vectors of R are presumed to rotate with constant angular */
181 /* velocity, we will first find the rotation axis of the quotient */
182 /* rotation Q that maps the row vectors of R from their initial to */
183 /* final position. Since the rows of R are the columns of the */
184 /* transpose of R, we can write: */
185
186 /* T T */
187 /* R(t1) = Q * R(t0), */
188
189 /* Since */
190
191 /* T T T */
192 /* R(t1) = ( R(t1) * R(t0) ) * R(t0) */
193
194
195 /* we can find Q, as well as a rotation axis A and an angle THETA */
196 /* in the range [0, pi] such that Q rotates vectors by THETA */
197 /* radians about axis A. */
198
199 /* We'll use the notation */
200
201 /* [ x ] */
202 /* N */
203
204 /* to indicate a coordinate system rotation of x radians about the */
205 /* vector N. Having found A and THETA, we can write (note that */
206 /* the sign of the rotation angle is negated because we're using */
207 /* a coordinate system rotation) */
208
209 /* T (t - t0) T */
210 /* R(t) = [ - THETA * --------- ] * R(t0) */
211 /* (t1 - t0) A */
212
213 /* Thus R(t) and QINTRP are determined. */
214
215 /* The input argument FRAC plays the role of the quotient */
216
217 /* t - t0 */
218 /* ------- */
219 /* t1 - t0 */
220
221 /* shown above. */
222
223
224 /* $ Examples */
225
226 /* 1) Suppose we want to interpolate between quaternions */
227 /* Q1 and Q2 that give the orientation of a spacecraft structure */
228 /* at times t1 and t2. We wish to find an approximation of the */
229 /* structure's orientation at the midpoint of the time interval */
230 /* [t1, t2]. We assume that the angular velocity of the */
231 /* structure equals the constant AV between times t1 and t2. We */
232 /* also assume that */
233
234 /* || AV || * (t2 - t1) < pi. */
235
236 /* Then the code fragment */
237
238 /* CALL QMINI ( Q1, Q2, 0.5D0, QINTRP, SCLDAV ) */
239
240 /* produces the approximation we desire. */
241
242
243
244 /* $ Restrictions */
245
246 /* None. */
247
248 /* $ Literature_References */
249
250 /* None. */
251
252 /* $ Author_and_Institution */
253
254 /* N.J. Bachman (JPL) */
255
256 /* $ Version */
257
258 /* - SPICELIB Version 1.0.0, 19-JUL-2005 (NJB) */
259
260 /* -& */
261 /* $ Index_Entries */
262
263 /* linear interpolation between quaternions */
264
265 /* -& */
266
267 /* SPICELIB functions */
268
269
270 /* Local variables */
271
272
273 /* Use discovery check-in. */
274
275
276
277 /* Find the conjugate INSTAR of the input quaternion INIT. */
278
279 instar[0] = init[0];
280 vminus_c(&init[1], &instar[1]);
281
282 /* Find the quotient quaternion Q that maps INIT to FINAL. */
283
284 qxq_c(final, instar, q);
285
286 /* Extract the rotation angle from Q. Use arccosine for */
287 /* speed, sacrificing some accuracy. */
288
289 angle = acos(brcktd_c(q[0], c_b2, c_b3)) * 2.;
290
291 /* Create a quaternion QSCALE from the rotation axis of the quotient */
292 /* and the scaled rotation angle. */
293
294 intang = frac * angle / 2.;
295 qscale[0] = cos(intang);
296
297 /* Get the unit vector parallel to the vector part of Q. */
298 /* UNORM does exactly what we want here, because if the vector */
299 /* part of Q is zero, the returned "unit" vector will be the */
300 /* zero vector. */
301
302 unorm_c(&q[1], axis, &vmag);
303
304 /* Form the vector part of QSCALE. */
305
306 d__1 = sin(intang);
307 vscl_c(d__1, axis, &qscale[1]);
308
309 /* Apply QSCALE to INIT to produce the interpolated quaternion we */
310 /* seek. */
311
312 qxq_c(qscale, init, qintrp);
313 return 0;
314} /* qmini_ */
315
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
Namespace for the standard library.