1 /*
2 *+
3 *  Name:
4 *     palDeuler
5 
6 *  Purpose:
7 *     Form a rotation matrix from the Euler angles
8 
9 *  Language:
10 *     Starlink ANSI C
11 
12 *  Type of Module:
13 *     Library routine
14 
15 *  Invocation:
16 *     void palDeuler ( const char *order, double phi, double theta, double psi,
17 *                      double rmat[3][3] );
18 
19 *  Arguments:
20 *     order = const char[] (Given)
21 *        Specifies about which axes the rotation occurs
22 *     phi = double (Given)
23 *        1st rotation (radians)
24 *     theta = double (Given)
25 *        2nd rotation (radians)
26 *     psi = double (Given)
27 *        3rd rotation (radians)
28 *     rmat = double[3][3] (Given & Returned)
29 *        Rotation matrix
30 
31 *  Description:
32 *     A rotation is positive when the reference frame rotates
33 *     anticlockwise as seen looking towards the origin from the
34 *     positive region of the specified axis.
35 *
36 *     The characters of ORDER define which axes the three successive
37 *     rotations are about.  A typical value is 'ZXZ', indicating that
38 *     RMAT is to become the direction cosine matrix corresponding to
39 *     rotations of the reference frame through PHI radians about the
40 *     old Z-axis, followed by THETA radians about the resulting X-axis,
41 *     then PSI radians about the resulting Z-axis.
42 *
43 *     The axis names can be any of the following, in any order or
44 *     combination:  X, Y, Z, uppercase or lowercase, 1, 2, 3.  Normal
45 *     axis labelling/numbering conventions apply;  the xyz (=123)
46 *     triad is right-handed.  Thus, the 'ZXZ' example given above
47 *     could be written 'zxz' or '313' (or even 'ZxZ' or '3xZ').  ORDER
48 *     is terminated by length or by the first unrecognized character.
49 *
50 *     Fewer than three rotations are acceptable, in which case the later
51 *     angle arguments are ignored.  If all rotations are zero, the
52 *     identity matrix is produced.
53 
54 *  Authors:
55 *     PTW: Pat Wallace (STFC)
56 *     TIMJ: Tim Jenness (JAC, Hawaii)
57 *     {enter_new_authors_here}
58 
59 *  History:
60 *     2012-02-08 (TIMJ):
61 *        Initial version with documentation taken from Fortran SLA
62 *        Adapted with permission from the Fortran SLALIB library.
63 *     {enter_further_changes_here}
64 
65 *  Copyright:
66 *     Copyright (C) 1997 Rutherford Appleton Laboratory
67 *     Copyright (C) 2012 Science and Technology Facilities Council.
68 *     All Rights Reserved.
69 
70 *  Licence:
71 *     This program is free software: you can redistribute it and/or
72 *     modify it under the terms of the GNU Lesser General Public
73 *     License as published by the Free Software Foundation, either
74 *     version 3 of the License, or (at your option) any later
75 *     version.
76 *
77 *     This program is distributed in the hope that it will be useful,
78 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
79 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
80 *     GNU Lesser General Public License for more details.
81 *
82 *     You should have received a copy of the GNU Lesser General
83 *     License along with this program.  If not, see
84 *     <http://www.gnu.org/licenses/>.
85 
86 *  Bugs:
87 *     {note_any_bugs_here}
88 *-
89 */
90 
91 #include "pal.h"
92 #include "pal1sofa.h"
93 
94 void
palDeuler(const char * order,double phi,double theta,double psi,double rmat[3][3])95 palDeuler( const char *order, double phi, double theta, double psi,
96                  double rmat[3][3] ) {
97   int i = 0;
98   double rotations[3];
99 
100   /* Initialise rmat */
101   eraIr( rmat );
102 
103   /* copy the rotations into an array */
104   rotations[0] = phi;
105   rotations[1] = theta;
106   rotations[2] = psi;
107 
108   /* maximum three rotations */
109   while (i < 3 && order[i] != '\0') {
110 
111     switch (order[i]) {
112     case 'X':
113     case 'x':
114     case '1':
115       eraRx( rotations[i], rmat );
116       break;
117 
118     case 'Y':
119     case 'y':
120     case '2':
121       eraRy( rotations[i], rmat );
122       break;
123 
124     case 'Z':
125     case 'z':
126     case '3':
127       eraRz( rotations[i], rmat );
128       break;
129 
130     default:
131       /* break out the loop if we do not recognize something */
132       i = 3;
133 
134     }
135 
136     /* Go to the next position */
137     i++;
138   }
139 
140   return;
141 }
142