| 1 | #include "slalib.h"
|
|---|
| 2 | #include "slamac.h"
|
|---|
| 3 | #include <string.h>
|
|---|
| 4 | void slaDeuler ( char *order, double phi, double theta,
|
|---|
| 5 | double psi, double rmat[3][3] )
|
|---|
| 6 | /*
|
|---|
| 7 | ** - - - - - - - - - -
|
|---|
| 8 | ** s l a D e u l e r
|
|---|
| 9 | ** - - - - - - - - - -
|
|---|
| 10 | **
|
|---|
| 11 | ** Form a rotation matrix from the Euler angles - three successive
|
|---|
| 12 | ** rotations about specified Cartesian axes.
|
|---|
| 13 | **
|
|---|
| 14 | ** (double precision)
|
|---|
| 15 | **
|
|---|
| 16 | ** Given:
|
|---|
| 17 | ** *order char specifies about which axes the rotations occur
|
|---|
| 18 | ** phi double 1st rotation (radians)
|
|---|
| 19 | ** theta double 2nd rotation ( " )
|
|---|
| 20 | ** psi double 3rd rotation ( " )
|
|---|
| 21 | **
|
|---|
| 22 | ** Returned:
|
|---|
| 23 | ** rmat double[3][3] rotation matrix
|
|---|
| 24 | **
|
|---|
| 25 | ** A rotation is positive when the reference frame rotates
|
|---|
| 26 | ** anticlockwise as seen looking towards the origin from the
|
|---|
| 27 | ** positive region of the specified axis.
|
|---|
| 28 | **
|
|---|
| 29 | ** The characters of order define which axes the three successive
|
|---|
| 30 | ** rotations are about. A typical value is 'zxz', indicating that
|
|---|
| 31 | ** rmat is to become the direction cosine matrix corresponding to
|
|---|
| 32 | ** rotations of the reference frame through phi radians about the
|
|---|
| 33 | ** old z-axis, followed by theta radians about the resulting x-axis,
|
|---|
| 34 | ** then psi radians about the resulting z-axis.
|
|---|
| 35 | **
|
|---|
| 36 | ** The axis names can be any of the following, in any order or
|
|---|
| 37 | ** combination: x, y, z, uppercase or lowercase, 1, 2, 3. Normal
|
|---|
| 38 | ** axis labelling/numbering conventions apply; the xyz (=123)
|
|---|
| 39 | ** triad is right-handed. Thus, the 'zxz' example given above
|
|---|
| 40 | ** could be written 'zxz' or '313' (or even 'zxz' or '3xz'). Order
|
|---|
| 41 | ** is terminated by length or by the first unrecognized character.
|
|---|
| 42 | **
|
|---|
| 43 | ** Fewer than three rotations are acceptable, in which case the later
|
|---|
| 44 | ** angle arguments are ignored. Zero rotations leaves rmat set to the
|
|---|
| 45 | ** identity matrix.
|
|---|
| 46 | **
|
|---|
| 47 | ** Last revision: 9 December 1996
|
|---|
| 48 | **
|
|---|
| 49 | ** Copyright P.T.Wallace. All rights reserved.
|
|---|
| 50 | */
|
|---|
| 51 | {
|
|---|
| 52 | int j, i, l, n, k;
|
|---|
| 53 | double result[3][3], rotn[3][3], angle, s, c , w, wm[3][3];
|
|---|
| 54 | char axis;
|
|---|
| 55 |
|
|---|
| 56 | /* Initialize result matrix */
|
|---|
| 57 | for ( j = 0; j < 3; j++ ) {
|
|---|
| 58 | for ( i = 0; i < 3; i++ ) {
|
|---|
| 59 | result[i][j] = ( i == j ) ? 1.0 : 0.0;
|
|---|
| 60 | }
|
|---|
| 61 | }
|
|---|
| 62 |
|
|---|
| 63 | /* Establish length of axis string */
|
|---|
| 64 | l = strlen ( order );
|
|---|
| 65 |
|
|---|
| 66 | /* Look at each character of axis string until finished */
|
|---|
| 67 | for ( n = 0; n < 3; n++ ) {
|
|---|
| 68 | if ( n <= l ) {
|
|---|
| 69 |
|
|---|
| 70 | /* Initialize rotation matrix for the current rotation */
|
|---|
| 71 | for ( j = 0; j < 3; j++ ) {
|
|---|
| 72 | for ( i = 0; i < 3; i++ ) {
|
|---|
| 73 | rotn[i][j] = ( i == j ) ? 1.0 : 0.0;
|
|---|
| 74 | }
|
|---|
| 75 | }
|
|---|
| 76 |
|
|---|
| 77 | /* Pick up the appropriate Euler angle and take sine & cosine */
|
|---|
| 78 | switch ( n ) {
|
|---|
| 79 | case 0 :
|
|---|
| 80 | angle = phi;
|
|---|
| 81 | break;
|
|---|
| 82 | case 1 :
|
|---|
| 83 | angle = theta;
|
|---|
| 84 | break;
|
|---|
| 85 | default:
|
|---|
| 86 | angle = psi;
|
|---|
| 87 | break;
|
|---|
| 88 | }
|
|---|
| 89 | s = sin ( angle );
|
|---|
| 90 | c = cos ( angle );
|
|---|
| 91 |
|
|---|
| 92 | /* Identify the axis */
|
|---|
| 93 | axis = order[n];
|
|---|
| 94 | if ( ( axis == 'X' ) || ( axis == 'x' ) || ( axis == '1' ) ) {
|
|---|
| 95 |
|
|---|
| 96 | /* Matrix for x-rotation */
|
|---|
| 97 | rotn[1][1] = c;
|
|---|
| 98 | rotn[1][2] = s;
|
|---|
| 99 | rotn[2][1] = -s;
|
|---|
| 100 | rotn[2][2] = c;
|
|---|
| 101 | }
|
|---|
| 102 | else if ( ( axis == 'Y' ) || ( axis == 'y' ) || ( axis == '2' ) ) {
|
|---|
| 103 |
|
|---|
| 104 | /* Matrix for y-rotation */
|
|---|
| 105 | rotn[0][0] = c;
|
|---|
| 106 | rotn[0][2] = -s;
|
|---|
| 107 | rotn[2][0] = s;
|
|---|
| 108 | rotn[2][2] = c;
|
|---|
| 109 | }
|
|---|
| 110 | else if ( ( axis == 'Z' ) || ( axis == 'z' ) || ( axis == '3' ) ) {
|
|---|
| 111 |
|
|---|
| 112 | /* Matrix for z-rotation */
|
|---|
| 113 | rotn[0][0] = c;
|
|---|
| 114 | rotn[0][1] = s;
|
|---|
| 115 | rotn[1][0] = -s;
|
|---|
| 116 | rotn[1][1] = c;
|
|---|
| 117 | } else {
|
|---|
| 118 |
|
|---|
| 119 | /* Unrecognized character - fake end of string */
|
|---|
| 120 | l = 0;
|
|---|
| 121 | }
|
|---|
| 122 |
|
|---|
| 123 | /* Apply the current rotation (matrix rotn x matrix result) */
|
|---|
| 124 | for ( i = 0; i < 3; i++ ) {
|
|---|
| 125 | for ( j = 0; j < 3; j++ ) {
|
|---|
| 126 | w = 0.0;
|
|---|
| 127 | for ( k = 0; k < 3; k++ ) {
|
|---|
| 128 | w += rotn[i][k] * result[k][j];
|
|---|
| 129 | }
|
|---|
| 130 | wm[i][j] = w;
|
|---|
| 131 | }
|
|---|
| 132 | }
|
|---|
| 133 | for ( j = 0; j < 3; j++ ) {
|
|---|
| 134 | for ( i= 0; i < 3; i++ ) {
|
|---|
| 135 | result[i][j] = wm[i][j];
|
|---|
| 136 | }
|
|---|
| 137 | }
|
|---|
| 138 | }
|
|---|
| 139 | }
|
|---|
| 140 |
|
|---|
| 141 | /* Copy the result */
|
|---|
| 142 | for ( j = 0; j < 3; j++ ) {
|
|---|
| 143 | for ( i = 0; i < 3; i++ ) {
|
|---|
| 144 | rmat[i][j] = result[i][j];
|
|---|
| 145 | }
|
|---|
| 146 | }
|
|---|
| 147 | }
|
|---|