00001
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "generic.h"
00015 #include "mathop.h"
00016 #include "rodrigues.h"
00017
00018 #include <math.h>
00019
00026 void
00027 vl_rodrigues(double* R_pt, double* dR_pt, const double* om_pt)
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 #define OM(i) om_pt[(i)]
00054 #define R(i,j) R_pt[(i)+3*(j)]
00055 #define DR(i,j) dR_pt[(i)+9*(j)]
00056 #undef small
00057
00058 const double small = 1e-6 ;
00059
00060 double th = sqrt( OM(0)*OM(0) +
00061 OM(1)*OM(1) +
00062 OM(2)*OM(2) ) ;
00063
00064 if( th < small ) {
00065 R(0,0) = 1.0 ; R(0,1) = 0.0 ; R(0,2) = 0.0 ;
00066 R(1,0) = 0.0 ; R(1,1) = 1.0 ; R(1,2) = 0.0 ;
00067 R(2,0) = 0.0 ; R(2,1) = 0.0 ; R(2,2) = 1.0 ;
00068
00069 if(dR_pt) {
00070 DR(0,0) = 0 ; DR(0,1) = 0 ; DR(0,2) = 0 ;
00071 DR(1,0) = 0 ; DR(1,1) = 0 ; DR(1,2) = 1 ;
00072 DR(2,0) = 0 ; DR(2,1) = -1 ; DR(2,2) = 0 ;
00073
00074 DR(3,0) = 0 ; DR(3,1) = 0 ; DR(3,2) = -1 ;
00075 DR(4,0) = 0 ; DR(4,1) = 0 ; DR(4,2) = 0 ;
00076 DR(5,0) = 1 ; DR(5,1) = 0 ; DR(5,2) = 0 ;
00077
00078 DR(6,0) = 0 ; DR(6,1) = 1 ; DR(6,2) = 0 ;
00079 DR(7,0) = -1 ; DR(7,1) = 0 ; DR(7,2) = 0 ;
00080 DR(8,0) = 0 ; DR(8,1) = 0 ; DR(8,2) = 0 ;
00081 }
00082 return ;
00083 }
00084
00085 {
00086 double x = OM(0) / th ;
00087 double y = OM(1) / th ;
00088 double z = OM(2) / th ;
00089
00090 double xx = x*x ;
00091 double xy = x*y ;
00092 double xz = x*z ;
00093 double yy = y*y ;
00094 double yz = y*z ;
00095 double zz = z*z ;
00096
00097 const double yx = xy ;
00098 const double zx = xz ;
00099 const double zy = yz ;
00100
00101 double sth = sin(th) ;
00102 double cth = cos(th) ;
00103 double mcth = 1.0 - cth ;
00104
00105 R(0,0) = 1 - mcth * (yy+zz) ;
00106 R(1,0) = sth*z + mcth * xy ;
00107 R(2,0) = - sth*y + mcth * xz ;
00108
00109 R(0,1) = - sth*z + mcth * yx ;
00110 R(1,1) = 1 - mcth * (zz+xx) ;
00111 R(2,1) = sth*x + mcth * yz ;
00112
00113 R(0,2) = sth*y + mcth * xz ;
00114 R(1,2) = - sth*x + mcth * yz ;
00115 R(2,2) = 1 - mcth * (xx+yy) ;
00116
00117 if(dR_pt) {
00118 double a = sth / th ;
00119 double b = mcth / th ;
00120 double c = cth - a ;
00121 double d = sth - 2*b ;
00122
00123 DR(0,0) = - d * (yy+zz) * x ;
00124 DR(1,0) = b*y + c * zx + d * xy * x ;
00125 DR(2,0) = b*z - c * yx + d * xz * x ;
00126
00127 DR(3,0) = b*y - c * zx + d * xy * x ;
00128 DR(4,0) = -2*b*x - d * (zz+xx) * x ;
00129 DR(5,0) = a + c * xx + d * yz * x ;
00130
00131 DR(6,0) = b*z + c * yx + d * zx * x ;
00132 DR(7,0) = -a - c * xx + d * zy * x ;
00133 DR(8,0) = -2*b*x - d * (yy+xx) * x ;
00134
00135 DR(0,1) = -2*b*y - d * (yy+zz) * y ;
00136 DR(1,1) = b*x + c * zy + d * xy * y ;
00137 DR(2,1) = -a - c * yy + d * xz * y ;
00138
00139 DR(3,1) = b*x - c * zy + d * xy * y ;
00140 DR(4,1) = - d * (zz+xx) * y ;
00141 DR(5,1) = b*z + c * xy + d * yz * y ;
00142
00143 DR(6,1) = a + c * yy + d * zx * y ;
00144 DR(7,1) = b*z - c * xy + d * zy * y ;
00145 DR(8,1) = -2*b*y - d * (yy+xx) * y ;
00146
00147 DR(0,2) = -2*b*z - d * (yy+zz) * z ;
00148 DR(1,2) = a + c * zz + d * xy * z ;
00149 DR(2,2) = b*x - c * yz + d * xz * z ;
00150
00151 DR(3,2) = -a - c * zz + d * xy * z ;
00152 DR(4,2) = -2*b*z - d * (zz+xx) * z ;
00153 DR(5,2) = b*y + c * xz + d * yz * z ;
00154
00155 DR(6,2) = b*x + c * yz + d * zx * z ;
00156 DR(7,2) = b*y - c * xz + d * zy * z ;
00157 DR(8,2) = - d * (yy+xx) * z ;
00158 }
00159 }
00160
00161 #undef OM
00162 #undef R
00163 #undef DR
00164
00165 }
00166
00178 VL_EXPORT
00179 void vl_irodrigues(double* om_pt, double* dom_pt, const double* R_pt)
00180 {
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 #define OM(i) om_pt[(i)]
00196 #define DOM(i,j) dom_pt[(i)+3*(j)]
00197 #define R(i,j) R_pt[(i)+3*(j)]
00198 #define W(i,j) W_pt[(i)+3*(j)]
00199
00200 const double small = 1e-6 ;
00201
00202 double th = acos
00203 (0.5*(VL_MAX(R(0,0)+R(1,1)+R(2,2),-1.0) - 1.0)) ;
00204
00205 double sth = sin(th) ;
00206 double cth = cos(th) ;
00207
00208 if(fabs(sth) < small && cth < 0) {
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 double W_pt [9], x, y, z ;
00223 W_pt[0] = 0.5*( R(0,0) + R(0,0) ) - 1.0 ;
00224 W_pt[1] = 0.5*( R(1,0) + R(0,1) ) ;
00225 W_pt[2] = 0.5*( R(2,0) + R(0,2) );
00226
00227 W_pt[3] = 0.5*( R(0,1) + R(1,0) );
00228 W_pt[4] = 0.5*( R(1,1) + R(1,1) ) - 1.0;
00229 W_pt[5] = 0.5*( R(2,1) + R(1,2) );
00230
00231 W_pt[6] = 0.5*( R(0,2) + R(2,0) ) ;
00232 W_pt[7] = 0.5*( R(1,2) + R(2,1) ) ;
00233 W_pt[8] = 0.5*( R(2,2) + R(2,2) ) - 1.0 ;
00234
00235
00236 x = sqrt( 0.5 * (W(0,0)-W(1,1)-W(2,2)) ) ;
00237 y = sqrt( 0.5 * (W(1,1)-W(2,2)-W(0,0)) ) ;
00238 z = sqrt( 0.5 * (W(2,2)-W(0,0)-W(1,1)) ) ;
00239
00240
00241
00242
00243 if( x >= y && x >= z ) {
00244 y = (W(1,0) >=0) ? y : -y ;
00245 z = (W(2,0) >=0) ? z : -z ;
00246 } else if( y >= x && y >= z ) {
00247 z = (W(2,1) >=0) ? z : -z ;
00248 x = (W(1,0) >=0) ? x : -x ;
00249 } else {
00250 x = (W(2,0) >=0) ? x : -x ;
00251 y = (W(2,1) >=0) ? y : -y ;
00252 }
00253
00254
00255
00256
00257 {
00258 double scale = th / sqrt( 1 - cth ) ;
00259 OM(0) = scale * x ;
00260 OM(1) = scale * y ;
00261 OM(2) = scale * z ;
00262
00263 if( dom_pt ) {
00264 int k ;
00265 for(k=0; k<3*9; ++k)
00266 dom_pt [k] = VL_NAN_D ;
00267 }
00268 return ;
00269 }
00270
00271 } else {
00272 double a = (fabs(sth) < small) ? 1 : th/sin(th) ;
00273 double b ;
00274 OM(0) = 0.5*a*(R(2,1) - R(1,2)) ;
00275 OM(1) = 0.5*a*(R(0,2) - R(2,0)) ;
00276 OM(2) = 0.5*a*(R(1,0) - R(0,1)) ;
00277
00278 if( dom_pt ) {
00279 if( fabs(sth) < small ) {
00280 a = 0.5 ;
00281 b = 0 ;
00282 } else {
00283 a = th/(2*sth) ;
00284 b = (th*cth - sth)/(2*sth*sth)/th ;
00285 }
00286
00287 DOM(0,0) = b*OM(0) ;
00288 DOM(1,0) = b*OM(1) ;
00289 DOM(2,0) = b*OM(2) ;
00290
00291 DOM(0,1) = 0 ;
00292 DOM(1,1) = 0 ;
00293 DOM(2,1) = a ;
00294
00295 DOM(0,2) = 0 ;
00296 DOM(1,2) = -a ;
00297 DOM(2,2) = 0 ;
00298
00299 DOM(0,3) = 0 ;
00300 DOM(1,3) = 0 ;
00301 DOM(2,3) = -a ;
00302
00303 DOM(0,4) = b*OM(0) ;
00304 DOM(1,4) = b*OM(1) ;
00305 DOM(2,4) = b*OM(2) ;
00306
00307 DOM(0,5) = a ;
00308 DOM(1,5) = 0 ;
00309 DOM(2,5) = 0 ;
00310
00311 DOM(0,6) = 0 ;
00312 DOM(1,6) = a ;
00313 DOM(2,6) = 0 ;
00314
00315 DOM(0,7) = -a ;
00316 DOM(1,7) = 0 ;
00317 DOM(2,7) = 0 ;
00318
00319 DOM(0,8) = b*OM(0) ;
00320 DOM(1,8) = b*OM(1) ;
00321 DOM(2,8) = b*OM(2) ;
00322 }
00323 }
00324
00325 #undef OM
00326 #undef DOM
00327 #undef R
00328 #undef W
00329 }