1 /* twovec.f -- translated by f2c (version 19980913).
2    You must link the resulting object file with the libraries:
3 	-lf2c -lm   (in that order)
4 */
5 
6 #include "f2c.h"
7 
8 /* Table of constant values */
9 
10 static integer c__9 = 9;
11 
12 /* $Procedure      TWOVEC ( Two vectors defining an orthonormal frame ) */
twovec_(doublereal * axdef,integer * indexa,doublereal * plndef,integer * indexp,doublereal * mout)13 /* Subroutine */ int twovec_(doublereal *axdef, integer *indexa, doublereal *
14 	plndef, integer *indexp, doublereal *mout)
15 {
16     /* Initialized data */
17 
18     static integer seqnce[5] = { 1,2,3,1,2 };
19 
20     /* System generated locals */
21     integer i__1, i__2, i__3;
22 
23     /* Builtin functions */
24     integer s_rnge(char *, integer, char *, integer);
25 
26     /* Local variables */
27     extern /* Subroutine */ int vhat_(doublereal *, doublereal *), chkin_(
28 	    char *, ftnlen), moved_(doublereal *, integer *, doublereal *);
29     doublereal mtemp[9]	/* was [3][3] */;
30     integer i1, i2, i3;
31     extern /* Subroutine */ int xpose_(doublereal *, doublereal *), ucrss_(
32 	    doublereal *, doublereal *, doublereal *), sigerr_(char *, ftnlen)
33 	    , chkout_(char *, ftnlen), setmsg_(char *, ftnlen), errint_(char *
34 	    , integer *, ftnlen);
35     extern logical return_(void);
36 
37 /* $ Abstract */
38 
39 /*     Find the transformation to the right-handed frame having a */
40 /*     given vector as a specified axis and having a second given */
41 /*     vector lying in a specified coordinate plane. */
42 
43 /* $ Disclaimer */
44 
45 /*     THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */
46 /*     CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */
47 /*     GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */
48 /*     ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */
49 /*     PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */
50 /*     TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */
51 /*     WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */
52 /*     PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */
53 /*     SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */
54 /*     SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */
55 
56 /*     IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */
57 /*     BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */
58 /*     LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */
59 /*     INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */
60 /*     REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */
61 /*     REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */
62 
63 /*     RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */
64 /*     THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */
65 /*     CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */
66 /*     ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */
67 
68 /* $ Required_Reading */
69 
70 /*     None. */
71 
72 /* $ Keywords */
73 
74 /*     AXES,  FRAME,  ROTATION,  TRANSFORMATION */
75 
76 /* $ Declarations */
77 /* $ Brief_I/O */
78 
79 /*     VARIABLE  I/O  DESCRIPTION */
80 /*     --------  ---  ------------------------------------------------- */
81 /*     AXDEF      I   Vector defining a principal axis. */
82 /*     INDEXA     I   Principal axis number of AXDEF (X=1, Y=2, Z=3). */
83 /*     PLNDEF     I   Vector defining (with AXDEF) a principal plane. */
84 /*     INDEXP     I   Second axis number (with INDEXA) of principal */
85 /*                     plane. */
86 /*     MOUT       O   Output rotation matrix. */
87 
88 /* $ Detailed_Input */
89 
90 /*     AXDEF      is a vector defining one of the priciple axes of a */
91 /*                coordinate frame. */
92 
93 /*     INDEXA     is a number that determines which of the three */
94 /*                coordinate axes contains AXDEF. */
95 
96 /*                If INDEXA is 1 then AXDEF defines the X axis of the */
97 /*                coordinate frame. */
98 
99 /*                If INDEXA is 2 then AXDEF defines the Y axis of the */
100 /*                coordinate frame. */
101 
102 /*                If INDEXA is 3 then AXDEF defines the Z axis of the */
103 /*                coordinate frame */
104 
105 /*     PLNDEF     is a vector defining (with AXDEF) a principal plane of */
106 /*                the coordinate frame. AXDEF and PLNDEF must be */
107 /*                linearly independent. */
108 
109 /*     INDEXP     is the second axis of the principal frame determined */
110 /*                by AXDEF and PLNDEF.  INDEXA, INDEXP must be different */
111 /*                and be integers from 1 to 3. */
112 
113 /*                If INDEXP is 1, the second axis of the principal */
114 /*                plane is the X-axis. */
115 
116 /*                If INDEXP is 2, the second axis of the principal */
117 /*                plane is the Y-axis. */
118 
119 /*                If INDEXP is 3, the second axis of the principal plane */
120 /*                is the Z-axis. */
121 
122 
123 /* $ Detailed_Output */
124 
125 /*     MOUT       is a rotation matrix that transforms coordinates given */
126 /*                in the input frame to the frame determined by AXDEF, */
127 /*                PLNDEF, INDEXA and INDEXP. */
128 
129 /* $ Parameters */
130 
131 /*     None. */
132 
133 /* $ Exceptions */
134 
135 /*     1) If INDEXA or INDEXP is not in the set {1,2,3} the error */
136 /*        SPICE(BADINDEX) will be signaled. */
137 
138 /*     2) If INDEXA and INDEXP are the same the error */
139 /*        SPICE(UNDEFINEDFRAME) will be signaled. */
140 
141 /*     3) If the cross product of the vectors AXDEF and PLNDEF is zero, */
142 /*        the error SPICE(DEPENDENTVECTORS) will be signaled. */
143 
144 /* $ Files */
145 
146 /*     None. */
147 
148 /* $ Particulars */
149 
150 /*     Given two linearly independent vectors there is a unique */
151 /*     right-handed coordinate frame having: */
152 
153 /*        AXDEF lying along the INDEXA axis. */
154 
155 /*        PLNDEF lying in the INDEXA-INDEXP coordinate plane. */
156 
157 /*     This routine determines the transformation matrix that transforms */
158 /*     from coordinates used to represent the input vectors to the */
159 /*     the system determined by AXDEF and PLNDEF.  Thus a vector */
160 /*     (x,y,z) in the input coordinate system will have coordinates */
161 
162 /*                     t */
163 /*        MOUT* (x,y,z) */
164 
165 /*     in the frame determined by AXDEF and PLNDEF. */
166 
167 /* $ Examples */
168 
169 /*     The rotation matrix TICC from inertial to Sun-Canopus */
170 /*     (celestial) coordinates is found by the call */
171 
172 /*        CALL TWOVEC (Sun vector, 3, Canopus vector, 1, TICC) */
173 
174 /* $ Restrictions */
175 
176 /*     None. */
177 
178 /* $ Author_and_Institution */
179 
180 /*     N.J. Bachman    (JPL) */
181 /*     W.M. Owen       (JPL) */
182 /*     W.L. Taber      (JPL) */
183 
184 /* $ Literature_References */
185 
186 /*     None. */
187 
188 /* $ Version */
189 
190 /* -    SPICELIB Version 1.1.0, 31-AUG-2005 (NJB) */
191 
192 /*        Updated to remove non-standard use of duplicate arguments */
193 /*        in VSCL call. */
194 
195 /* -    SPICELIB Version 1.0.1, 10-MAR-1992 (WLT) */
196 
197 /*        Comment section for permuted index source lines was added */
198 /*        following the header. */
199 
200 /* -    SPICELIB Version 1.0.0,  31-JAN-1990 (WMO) */
201 
202 /* -& */
203 /* $ Index_Entries */
204 
205 /*     define an orthonormal frame from two vectors */
206 
207 /* -& */
208 /* $ Revisions */
209 
210 /* -    SPICELIB Version 1.1.0, 31-AUG-2005 (NJB) */
211 
212 /*        Updated to remove non-standard use of duplicate arguments */
213 /*        in VSCL call. */
214 
215 /* -    Beta Version 2.0.0, 10-JAN-1989 (WLT) */
216 
217 /*     Error checking was added and the algorithm somewhat redesigned. */
218 /* -& */
219 
220 /*     SPICELIB functions */
221 
222 
223 /*     Local variables */
224 
225 
226 /*     Saved variables */
227 
228 
229 /*     Initial values */
230 
231 
232 /*     Standard SPICE error handling */
233 
234     if (return_()) {
235 	return 0;
236     } else {
237 	chkin_("TWOVEC", (ftnlen)6);
238     }
239 
240 /*     Check for obvious bad inputs. */
241 
242     if (max(*indexp,*indexa) > 3 || min(*indexp,*indexa) < 1) {
243 	setmsg_("The definition indexs must lie in the range from 1 to 3.  T"
244 		"he value of INDEXA was #. The value of INDEXP was #. ", (
245 		ftnlen)112);
246 	errint_("#", indexa, (ftnlen)1);
247 	errint_("#", indexp, (ftnlen)1);
248 	sigerr_("SPICE(BADINDEX)", (ftnlen)15);
249 	chkout_("TWOVEC", (ftnlen)6);
250 	return 0;
251     } else if (*indexa == *indexp) {
252 	setmsg_("The values of INDEXA and INDEXP were the same, namely #.  T"
253 		"hey are required to be different.", (ftnlen)92);
254 	errint_("#", indexa, (ftnlen)1);
255 	sigerr_("SPICE(UNDEFINEDFRAME)", (ftnlen)21);
256 	chkout_("TWOVEC", (ftnlen)6);
257 	return 0;
258     }
259 
260 /*     Get indices for right-handed axes */
261 
262 /*     First AXDEF ... */
263 
264     i1 = *indexa;
265 
266 /*     ... then the other two. */
267 
268     i2 = seqnce[(i__1 = *indexa) < 5 && 0 <= i__1 ? i__1 : s_rnge("seqnce",
269 	    i__1, "twovec_", (ftnlen)270)];
270     i3 = seqnce[(i__1 = *indexa + 1) < 5 && 0 <= i__1 ? i__1 : s_rnge("seqnce"
271 	    , i__1, "twovec_", (ftnlen)271)];
272 
273 /*     Row I1 contains normalized AXDEF (store in columns for now) */
274 
275     vhat_(axdef, &mout[(i__1 = i1 * 3 - 3) < 9 && 0 <= i__1 ? i__1 : s_rnge(
276 	    "mout", i__1, "twovec_", (ftnlen)276)]);
277 
278 /*     Obtain rows I2 and I3 using cross products.  Which order to use */
279 /*     depends on whether INDEXP = I2 (next axis in right-handed order) */
280 /*     or INDEXP = I3 (previous axis in right-handed order). */
281 
282     if (*indexp == i2) {
283 	ucrss_(axdef, plndef, &mout[(i__1 = i3 * 3 - 3) < 9 && 0 <= i__1 ?
284 		i__1 : s_rnge("mout", i__1, "twovec_", (ftnlen)285)]);
285 	ucrss_(&mout[(i__1 = i3 * 3 - 3) < 9 && 0 <= i__1 ? i__1 : s_rnge(
286 		"mout", i__1, "twovec_", (ftnlen)286)], axdef, &mout[(i__2 =
287 		i2 * 3 - 3) < 9 && 0 <= i__2 ? i__2 : s_rnge("mout", i__2,
288 		"twovec_", (ftnlen)286)]);
289     } else {
290 	ucrss_(plndef, axdef, &mout[(i__1 = i2 * 3 - 3) < 9 && 0 <= i__1 ?
291 		i__1 : s_rnge("mout", i__1, "twovec_", (ftnlen)290)]);
292 	ucrss_(axdef, &mout[(i__1 = i2 * 3 - 3) < 9 && 0 <= i__1 ? i__1 :
293 		s_rnge("mout", i__1, "twovec_", (ftnlen)291)], &mout[(i__2 =
294 		i3 * 3 - 3) < 9 && 0 <= i__2 ? i__2 : s_rnge("mout", i__2,
295 		"twovec_", (ftnlen)291)]);
296     }
297 
298 /*     Finally, check to see that we actually got something non-zero */
299 /*     in one of the one columns of MOUT(1,I2) and MOUT(1,I3) (we need */
300 /*     only check one of them since they are related by a cross product). */
301 
302     if (mout[(i__1 = i2 * 3 - 3) < 9 && 0 <= i__1 ? i__1 : s_rnge("mout",
303 	    i__1, "twovec_", (ftnlen)300)] == 0. && mout[(i__2 = i2 * 3 - 2) <
304 	     9 && 0 <= i__2 ? i__2 : s_rnge("mout", i__2, "twovec_", (ftnlen)
305 	    300)] == 0. && mout[(i__3 = i2 * 3 - 1) < 9 && 0 <= i__3 ? i__3 :
306 	    s_rnge("mout", i__3, "twovec_", (ftnlen)300)] == 0.) {
307 	setmsg_("The input vectors AXDEF and PLNDEF are linearly dependent.",
308 		(ftnlen)58);
309 	sigerr_("SPICE(DEPENDENTVECTORS)", (ftnlen)23);
310     }
311 
312 /*     Transpose MOUT. */
313 
314     xpose_(mout, mtemp);
315     moved_(mtemp, &c__9, mout);
316     chkout_("TWOVEC", (ftnlen)6);
317     return 0;
318 } /* twovec_ */
319 
320