| 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 | } | 
|---|