00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
#include <volume_io/internal_volume_io.h>
00082
#include <bicpl/trans.h>
00083
00084
#ifndef lint
00085
static char rcsid[] =
"$Header: /software/source//libraries/bicpl/Transforms/rotmat_to_ang.c,v 1.20 2000/02/06 15:30:51 stever Exp $";
00086
#endif
00087
00088
#ifdef DEBUG
00089
private void are_rotations_equivalent(
00090 Transform *rot_trans,
00091 Real rx,
00092 Real ry,
00093 Real rz );
00094
#endif
00095
00096 public BOOLEAN
rotmat_to_ang(
00097 Transform *rot_trans,
00098 Real *ang )
00099 {
00100 Real rx, ry, rz, vx, vy, vz, d;
00101 Vector x_axis, z_axis, y_axis, cross;
00102 Transform z_rot, y_rot;
00103
00104
00105
00106
00107
00108
00109
00110 get_transform_x_axis( rot_trans, &x_axis );
00111 get_transform_y_axis( rot_trans, &y_axis );
00112 get_transform_z_axis( rot_trans, &z_axis );
00113
00114
00115
00116
00117 CROSS_VECTORS( cross, x_axis, y_axis );
00118 d = DOT_VECTORS( cross, z_axis );
00119
00120
if( d < 0.0 )
00121 {
00122 print(
"rotmat_to_ang: warning, input transform is left-handed.\n" );
00123 SCALE_VECTOR( x_axis, x_axis, -1.0 );
00124 }
00125
else if( d == 0.0 )
00126 {
00127 print_error(
"rotmat_to_ang: singular system passed in.\n" );
00128
return(
FALSE );
00129 }
00130
00131
00132
00133
00134 rz =
compute_clockwise_rotation( (Real) Vector_x(x_axis),
00135 (Real) Vector_y(x_axis) );
00136
00137
if( rz >= PI )
00138 rz -= 2.0 * PI;
00139
00140
00141
00142
00143
make_rotation_transform( -rz, Z, &z_rot );
00144
00145 transform_vector( &z_rot, (Real) Vector_x(x_axis), (Real) Vector_y(x_axis),
00146 (Real) Vector_z(x_axis), &vx, &vy, &vz );
00147
00148 ry = -
compute_clockwise_rotation( vx, vz );
00149
00150
if( ry <= -PI )
00151 ry += 2.0 * PI;
00152
00153
00154
00155
make_rotation_transform( -ry, Y, &y_rot );
00156
00157 transform_vector( &z_rot, (Real) Vector_x(z_axis), (Real) Vector_y(z_axis),
00158 (Real) Vector_z(z_axis), &vx, &vy, &vz );
00159 transform_vector( &y_rot, vx, vy, vz, &vx, &vy, &vz );
00160
00161 rx = -
compute_clockwise_rotation( vz, vy );
00162
00163
if( rx <= -PI )
00164 rx += 2.0 * PI;
00165
00166
00167
00168
00169 rx = -rx;
00170 ry = -ry;
00171 rz = -rz;
00172
00173
#ifdef DEBUG
00174
{
00175 Transform test;
00176
00177 make_identity_transform( &test );
00178 set_transform_x_axis( &test, &x_axis );
00179 set_transform_y_axis( &test, &y_axis );
00180 set_transform_z_axis( &test, &z_axis );
00181
00182 are_rotations_equivalent( &test, rx, ry, rz );
00183 }
00184
#endif
00185
00186 ang[0] = rx;
00187 ang[1] = ry;
00188 ang[2] = rz;
00189
00190
return(
TRUE);
00191 }
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
#ifdef DEBUG
00211
private void are_rotations_equivalent(
00212 Transform *rot_trans,
00213 Real rx,
00214 Real ry,
00215 Real rz )
00216 {
00217 BOOLEAN error;
00218 Transform test, Rx, Ry, Rz;
00219
00220
00221
00222
make_rotation_transform( -rx, X, &Rx ) ;
00223
make_rotation_transform( -ry, Y, &Ry ) ;
00224
make_rotation_transform( -rz, Z, &Rz ) ;
00225
00226 concat_transforms( &test, &Rx, &Ry );
00227 concat_transforms( &test, &test, &Rz );
00228
00229
00230 error =
FALSE;
00231 for_less( m, 0, N_DIMENSIONS )
00232 for_less( n, 0, N_DIMENSIONS )
00233 if( !numerically_close( Transform_elem(test,m,n),
00234 Transform_elem(*rot_trans,m,n), 1.0e-3 ) )
00235 {
00236 error =
TRUE;
00237 }
00238
00239
if( error )
00240 {
00241 for_less( m, 0, N_DIMENSIONS )
00242 {
00243 for_less( n, 0, N_DIMENSIONS )
00244 print( " %g", Transform_elem(test,m,n) );
00245 print( "\n" );
00246 }
00247 print( "\n" );
00248 for_less( m, 0, N_DIMENSIONS )
00249 {
00250 for_less( n, 0, N_DIMENSIONS )
00251 print( " %g", Transform_elem(*rot_trans,m,n) );
00252 print( "\n" );
00253 }
00254
00255 handle_internal_error( "rotmat_to_ang" );
00256 }
00257 }
00258 #endif