src/common/sm_matrix.cc

00001 
00002 #include <math.h>
00003 #include "sm_matrix.h"
00004 
00005 
00006 void  smZero(vec3 A) {
00007         A[0] = A[1] = A[2] = 0; 
00008 }
00009 
00010 void smCopy(mat3 a, mat3 b) {
00011         b[0][0]=a[0][0];
00012         b[0][1]=a[0][1];
00013         b[0][2]=a[0][2];
00014         b[1][0]=a[1][0];
00015         b[1][1]=a[1][1];
00016         b[1][2]=a[1][2];
00017         b[2][0]=a[2][0];
00018         b[2][1]=a[2][1];
00019         b[2][2]=a[2][2];
00020 }
00021 
00022 void smCopy(vec3 a, vec3 b) {
00023         b[0]=a[0];
00024         b[1]=a[1];
00025         b[2]=a[2];
00026 }
00027 
00028 void smCopy(vec3 *a, vec3 *b, int len) {
00029         for ( int i = 0; i < len; i++) {        
00030                 b[i][0]=a[i][0];
00031                 b[i][1]=a[i][1];
00032                 b[i][2]=a[i][2];
00033         }
00034 }
00035 
00036 
00037 
00038 void smMultMat(mat3 a, mat3 b, mat3 c) {
00039         int i, j, k;
00040         for (i=0; i<3; i++) {
00041                 for (j=0; j<3; j++) {
00042                         c[i][j] = 0.0;
00043                         for (k=0; k<3; k++) {
00044                                 c[i][j] += a[i][k] * b[k][j];
00045                         }
00046                 }
00047         }
00048 }
00049 
00050 
00051 void smAdd(vec3 a, vec3 b) {
00052         b[0] += a[0];
00053         b[1] += a[1];
00054         b[2] += a[2];
00055 }
00056 
00057 void smAdd(vec3 a, vec3 b, vec3 c) {
00058         c[0] = a[0] + b[0];
00059         c[1] = a[1] + b[1];
00060         c[2] = a[2] + b[2];
00061 }
00062 
00063 void smAdd(vec3 a, vec3 *in_vec, int count) {
00064         for (int i = 0; i < count; i++) {
00065                 in_vec[i][0] += a[0];
00066                 in_vec[i][1] += a[1];
00067                 in_vec[i][2] += a[2];
00068         }
00069 }
00070 
00071 void smAdd(vec3 a, vec3 *in_vec, vec3 *out_vec, int count) {
00072         for (int i = 0; i < count; i++) {
00073                 out_vec[i][0] = in_vec[i][0] + a[0];
00074                 out_vec[i][1] = in_vec[i][1] + a[1];
00075                 out_vec[i][2] = in_vec[i][2] + a[2];
00076         }       
00077 }
00078 
00079 
00080 
00081 void smSub(vec3 a, vec3 b, vec3 c) {
00082         c[0] = a[0] - b[0];
00083         c[1] = a[1] - b[1];
00084         c[2] = a[2] - b[2];
00085 }
00086 
00087 
00088 void smSub(vec3 *in_vec, vec3 a, vec3 *out_vec, int count) {
00089         for (int i = 0; i < count; i++) {
00090                 out_vec[i][0] = in_vec[i][0] - a[0];
00091                 out_vec[i][1] = in_vec[i][1] - a[1];
00092                 out_vec[i][2] = in_vec[i][2] - a[2];
00093         }       
00094         
00095 }
00096 
00097 
00098 void smSub( vec3 a,  vec3 *in_vec, vec3 *out_vec, int count) {
00099         for (int i = 0; i < count; i++) {
00100                 out_vec[i][0] = a[0] - in_vec[i][0];
00101                 out_vec[i][1] = a[1] - in_vec[i][1];
00102                 out_vec[i][2] = a[2] - in_vec[i][2];
00103         }       
00104         
00105 }
00106 
00107 void smSub(vec3 *in_vec, vec3 a, int count) {
00108         for (int i = 0; i < count; i++) {
00109                 in_vec[i][0] -= a[0];
00110                 in_vec[i][1] -= a[1];
00111                 in_vec[i][2] -= a[2];
00112         }
00113 }
00114 
00115 void smMultVec(vec3 a, mat3 b) {
00116         vec3 c;
00117         c[0] = a[0]*b[0][0] + a[1]*b[1][0] + a[2]*b[2][0];
00118         c[1] = a[0]*b[0][1] + a[1]*b[1][1] + a[2]*b[2][1];
00119         c[2] = a[0]*b[0][2] + a[1]*b[1][2] + a[2]*b[2][2];
00120         smCopy(c, a);
00121 }
00122 
00123 void smMultVec(vec3 a, mat3 b, vec3 a_out) {
00124         a_out[0] = a[0]*b[0][0] + a[1]*b[1][0] + a[2]*b[2][0];
00125         a_out[1] = a[0]*b[0][1] + a[1]*b[1][1] + a[2]*b[2][1];
00126         a_out[2] = a[0]*b[0][2] + a[1]*b[1][2] + a[2]*b[2][2];
00127 }
00128 
00129 
00130 void smMultVec(vec3 *a, mat3 b, int len) {
00131         for (int i = 0; i < len; i++) {
00132                 smMultVec( a[i], b );
00133         }
00134 }
00135 
00136 void smMultVec(vec3 *a, mat3 b, vec3 *a_out, int len) {
00137         for (int i = 0; i < len; i++) {
00138                 smMultVec( a[i], b, a_out[i] );
00139         }
00140 }
00141 
00142 float smDotProduct(vec3 a, vec3 b) {
00143         return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
00144 }
00145 
00146 
00147 void smMultMat( mat3 u, vec3 in_vec) {
00148         vec3 tmp_vec;
00149         tmp_vec[0] = 0;
00150         tmp_vec[1] = 0;
00151         tmp_vec[2] = 0;
00152         for (int i = 0; i < 3; i++) {
00153                 for (int j = 0; j < 3; j++) {
00154                         tmp_vec[i] += u[i][j] * in_vec[j]; 
00155                 }
00156         }
00157         in_vec[0] = tmp_vec[0];
00158         in_vec[1] = tmp_vec[1];
00159         in_vec[2] = tmp_vec[2];
00160 }
00161 
00162 void smMultMat( mat3 u, vec3 *in_vec, vec3 *out_vec, int len) {
00163         vec3 tmp_vec;
00164         long n,i,j;     
00165         for (n = 0; n < len; n++) {
00166                 tmp_vec[0] = 0;
00167                 tmp_vec[1] = 0;
00168                 tmp_vec[2] = 0;
00169                 for (i = 0; i < 3; i++) {
00170                         for (j = 0; j < 3; j++) {
00171                                 tmp_vec[i] += u[i][j] * in_vec[n][j]; 
00172                         }
00173                 }
00174                 out_vec[n][0] = tmp_vec[0];
00175                 out_vec[n][1] = tmp_vec[1];
00176                 out_vec[n][2] = tmp_vec[2];
00177         }
00178 }
00179 
00180 void smMultMat( mat3 u, vec3 *in_vec, int len) {
00181         vec3 tmp_vec;
00182         long n,i,j;     
00183         for (n = 0; n < len; n++) {
00184                 tmp_vec[0] = 0;
00185                 tmp_vec[1] = 0;
00186                 tmp_vec[2] = 0;
00187                 for (i = 0; i < 3; i++) {
00188                         for (j = 0; j < 3; j++) {
00189                                 tmp_vec[i] += u[i][j] * in_vec[n][j]; 
00190                         }
00191                 }
00192                 in_vec[n][0] = tmp_vec[0];
00193                 in_vec[n][1] = tmp_vec[1];
00194                 in_vec[n][2] = tmp_vec[2];
00195         }
00196 }
00197 
00198 float smDistance(vec3 a, vec3 b) {
00199         vec3 tmp;
00200         tmp[0] = a[0] - b[0];
00201         tmp[1] = a[1] - b[1];
00202         tmp[2] = a[2] - b[2];
00203         return sqrt( tmp[0]*tmp[0] + tmp[1]*tmp[1] + tmp[2]*tmp[2] );
00204 }
00205 
00206 int smInverseMatrix(float original_matrix[3][3], float inverse_matrix[3][3]) {
00207 #define N 3
00208         float a[N*N];
00209         int is[N], js[N];
00210         int i, j, k, l, u, v;
00211         float d, p;
00212         
00213         for (i=0; i<N; i++) {
00214                 for (j=0; j<N; j++) {
00215                         a[i*N+j] = original_matrix[i][j];
00216                 }
00217         }
00218         for (k=0; k<N; k++) {
00219                 d = 0.0;
00220                 for (i=k; i<N; i++) {
00221                         for (j=k; j<N; j++) {
00222                                 l = i*N+j;
00223                                 p = fabs(a[l]);
00224                                 if (p>d) {
00225                                         d = p;
00226                                         is[k]=i;
00227                                         js[k] = j;
00228                                 }
00229                         }
00230                 }
00231                 if (d+1.0 == 1.0) {
00232                         //      printf( "Error: Inverse Matrix failed...\n");
00233                         //      fflush(stdout);
00234                         //      exit(0);
00235                         return(1);
00236                 }
00237                 if (is[k] != k) {
00238                         for (j=0; j<N; j++) {
00239                                 u = k*N+j;
00240                                 v = is[k]*N+j;
00241                                 p = a[u];
00242                                 a[u] = a[v];
00243                                 a[v] = p;
00244                         }
00245                 }
00246                 if (js[k] != k) {
00247                         for (i=0; i<N; i++) {
00248                                 u = i*N+k;
00249                                 v = i*N+js[k];
00250                                 p = a[u];
00251                                 a[u] = a[v];
00252                                 a[v] = p;
00253                         }
00254                 }
00255                 l = k*N+k;
00256                 a[l] = 1.0/a[l];
00257                 for (j=0; j<N; j++) {
00258                         if (j!=k) {
00259                                 u = k*N+j;
00260                                 a[u] = a[u]*a[l];
00261                         }
00262                 }
00263                 for (i=0; i<N; i++) {
00264                         if (i!=k) {
00265                                 for (j=0; j<N; j++) {
00266                                         if (j!= k) {
00267                                                 u = i*N+j;
00268                                                 a[u] = a[u] - a[i*N+k]*a[k*N+j];
00269                                         }
00270                                 }
00271                         }
00272                 }
00273                 for (i=0; i<N; i++) {
00274                         if (i!=k) {
00275                                 u = i*N+k;
00276                                 a[u] = -a[u]*a[l];
00277                         }
00278                 }
00279         }
00280         for (k=N-1; k>=0; k--) {
00281                 if (js[k] != k) {
00282                         for (j=0; j<N; j++) {
00283                                 u = k*N+j;
00284                                 v = js[k]*N+j;
00285                                 p = a[u];
00286                                 a[u] = a[v];
00287                                 a[v] = p;
00288                         }
00289                 }
00290                 if (is[k] != k) {
00291                         for (i=0; i<N; i++) {
00292                                 u = i*N+k;
00293                                 v = i*N+is[k];
00294                                 p = a[u];
00295                                 a[u] = a[v];
00296                                 a[v] = p;
00297                         }
00298                 }
00299         }
00300         for (i=0; i<N; i++)
00301                 for (j=0; j<N; j++)
00302                         inverse_matrix[i][j] = a[i*N+j];
00303         return(0);
00304 #undef N
00305 }
00306 
00307 
00308 
00309 void smMinus(vec3 a) {
00310         a[0] *= -1.0;
00311         a[1] *= -1.0;
00312         a[2] *= -1.0;
00313 }
00314 
00315 float smNorm(vec3 a) {  
00316         return sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]);
00317 }
00318 
00319 
00320 void smNormalize(vec3 a) {
00321         float norm;
00322         norm = smNorm(a);
00323         a[0] /= norm;
00324         a[1] /= norm;
00325         a[2] /= norm;
00326         return;
00327 }
00328 
00329 
00330 void smCrossProduct(vec3 a, vec3 b, vec3 c) {
00331         c[0] = a[1]*b[2] - a[2]*b[1];
00332         c[1] = a[2]*b[0] - a[0]*b[2];
00333         c[2] = a[0]*b[1] - a[1]*b[0];
00334 }
00335 
00336 
00337 
00338 void smComputeConvertMatrix(vec3 a, vec3 b, vec3 c, float convert_matrix[3][3]) {       
00339         int i;
00340         vec3 t_vector;
00341         vec3 origin_point, base_vector[3];
00342         
00343         /* get future origin point coordinates */
00344         smCopy(a, origin_point);
00345         
00346         /* determine base vectors of new coordinate system */
00347         smSub(b, a, base_vector[0] );
00348         smNormalize( base_vector[0] );
00349         
00350         smSub(c, a, t_vector );
00351         smCrossProduct(base_vector[0], t_vector, base_vector[2] );
00352         smNormalize( base_vector[2] );
00353         
00354         smCrossProduct(base_vector[2], base_vector[0], base_vector[1] );
00355         smNormalize( base_vector[1] );
00356         
00357         /* Make Convert Matrix */
00358         for (i=0; i<3; i++) {
00359                 convert_matrix[i][0] = base_vector[i][0];
00360                 convert_matrix[i][1] = base_vector[i][1];
00361                 convert_matrix[i][2] = base_vector[i][2];
00362         }
00363 }
00364 
00365 
00366 void smMakeRotationMatrix(float angle, vec3 C, float rot_mat[3][3]) {
00367         float u, w, v, f;
00368         float t;
00369         t = tan(angle/2.0);
00370         u = t*C[0]; 
00371         v = t*C[1]; 
00372         w = t*C[2]; 
00373         f = 1 / (1 + t*t);
00374         rot_mat[0][0] = f * (1 + u*u - v*v - w*w);
00375         rot_mat[0][1] = f * 2 * (u*v - w);
00376         rot_mat[0][2] = f * 2 * (u*w + v);
00377         rot_mat[1][0] = f * 2 * (u*v + w);
00378         rot_mat[1][1] = f * (1 - u*u + v*v - w*w);
00379         rot_mat[1][2] = f * 2 * (v*w - u);
00380         rot_mat[2][0] = f * 2 * (u*w - v);
00381         rot_mat[2][1] = f * 2 * (v*w + u);
00382         rot_mat[2][2] = f * (1 - u*u - v*v + w*w);
00383 }
00384 
00385 
00386 float smVectorAngle(vec3 point1, vec3 point2, vec3 center) {
00387         vec3 n1, n2;    
00388         smSub( point1, center, n1 );
00389         smSub( point2, center, n2 );    
00390         smNormalize( n1 );
00391         smNormalize( n2 );
00392         return acos( smDotProduct( n1, n2 ) );
00393 }
00394 
00395 
00396 
00397 float smVectorAngle(vec3 point1, vec3 point2) {
00398         vec3 n1, n2;    
00399         smCopy( point1, n1 );
00400         smCopy( point2, n2 );   
00401         smNormalize( n1 );
00402         smNormalize( n2 );
00403         return acos( smDotProduct( n1, n2 ) );
00404 }
00405 
00406 
00407 
00408 
00409 char smCalcMinRmsdRotation( vec3 *vec_a, vec3 *vec_b, int len, float matrix[3][3]) {
00410         double R[3][3], RT[3][3], RTR[3][3], eigen_val[3],
00411     eigen_vec[3][3] = { {0,0,0}, {0,0,0}, {0,0,0} }, b_mat[3][3];
00412         long n,i,j,k;
00413         double a, b, c, q, p, U1, U2, U3, U4, max_val, h,
00414                 i_val, j_val, k_val, L, M, N, P, tmp;
00415         double sum;
00416         
00417         for (i = 0; i < 3; i++) {
00418                 for (j = 0; j < 3; j++) {
00419                         R[i][j] = 0;
00420                         for (n = 0; n < len; n++) {
00421                                 R[i][j] += vec_b[n][i] * vec_a[n][j];
00422                         }
00423                 }
00424         }
00425         
00426         for (i = 0; i < 3; i++) {
00427                 for (j = 0; j < 3; j++) {
00428                         RT[j][i] = R[i][j]; 
00429                 }       
00430         }
00431         
00432         max_val = 0;
00433         for (i = 0; i < 3; i++) {
00434                 for (j = 0; j < 3; j++) {
00435                         RTR[i][j] = 0;
00436                         for (k = 0; k < 3; k++) {
00437                                 RTR[i][j] += RT[i][k] * R[k][j];
00438                                 if ( fabs(RTR[i][j]) > max_val ) 
00439                                         max_val = fabs(RTR[i][j]);
00440                         }
00441                 }
00442         }
00443         for (i = 0; i < 3; i++) {
00444                 for (j = 0; j < 3; j++) {
00445                         RTR[i][j] /= max_val;
00446                 }
00447         }
00448         
00449         //find the co-effiecents for the eigen value cubic equation
00450         a = -(
00451                   RTR[0][0] + 
00452                   RTR[1][1] + 
00453                   RTR[2][2]
00454                   );
00455         b = -(
00456                   -(RTR[0][0]*RTR[2][2]) - 
00457                   (RTR[1][1]*RTR[2][2]) - 
00458                   (RTR[0][0]*RTR[1][1]) + 
00459                   (RTR[0][2]*RTR[2][0]) +
00460                   (RTR[1][0]*RTR[0][1]) +
00461                   (RTR[1][2]*RTR[2][1])
00462                   );
00463         
00464         c = -(
00465                   (RTR[0][0]*RTR[1][1]*RTR[2][2]) +
00466                   (RTR[2][0]*RTR[0][1]*RTR[1][2]) +
00467                   (RTR[1][0]*RTR[0][2]*RTR[2][1]) -
00468                   (RTR[0][2]*RTR[1][1]*RTR[2][0]) -
00469                   (RTR[0][1]*RTR[1][0]*RTR[2][2]) -
00470                   (RTR[0][0]*RTR[1][2]*RTR[2][1])
00471                   );
00472         
00473         
00474         //apply cubic equation to find the actual eigen values
00475         
00476         p = b - (pow(a,2.0)/ 3.0);
00477         q = c + (2.0*pow(a,3.0) - 9.0*a*b) / 27.0;
00478         
00479         h = (pow(q,2.0)/4.0) + (pow(p,3.0)/27.0);
00480         
00481         i_val = sqrt( (pow(q,2.0) / 4.0) - h );
00482         j_val = cbrt( i_val );
00483         
00484         k_val = acos( -(q/ (2.0*i_val)) );
00485         
00486         L = j_val * -1; 
00487         M = cos(k_val/3.0);     
00488         N = sqrt(3.0) * sin( k_val / 3.0 );     
00489         P = (a/3.0 ) * -1;
00490         
00491         eigen_val[0] = 2 * j_val * cos(k_val/3.0) - (a/(3.0));
00492         eigen_val[1] = L * (M+N)+P;
00493         eigen_val[2] = L * (M-N)+P;
00494         
00495         double swap;
00496         if ( eigen_val[0] < eigen_val[1] ) {
00497                 swap = eigen_val[1];
00498                 eigen_val[1] = eigen_val[0];
00499                 eigen_val[0] = swap;
00500         }
00501         if ( eigen_val[1] < eigen_val[2] ) {
00502                 swap = eigen_val[2];
00503                 eigen_val[2] = eigen_val[1];
00504                 eigen_val[1] = swap;
00505                 if ( eigen_val[0] < eigen_val[1] ) {
00506                         swap = eigen_val[1];
00507                         eigen_val[1] = eigen_val[0];
00508                         eigen_val[0] = swap;
00509                 }
00510         }
00511         //for each of the eigen values, determine the eigen vector
00512         for (i = 0; i < 2; i++) {
00513                 U1 = (RTR[1][1] - eigen_val[i]) - 
00514                 (RTR[0][1] * RTR[1][0])
00515                 /(RTR[0][0]-eigen_val[i]);
00516                 U2 = (RTR[2][1]) - 
00517                         (RTR[0][1] * RTR[2][0])
00518                         /(RTR[0][0]-eigen_val[i]);
00519                 U3 = (RTR[1][2]) - 
00520                         (RTR[0][2] * RTR[1][0])
00521                         /(RTR[0][0]-eigen_val[i]);
00522                 U4 =  (RTR[2][2] - eigen_val[i]) - 
00523                         (RTR[0][2] * RTR[2][0])
00524                         /(RTR[0][0]-eigen_val[i]);
00525                 
00526                 if ( fabs(U4 - (U2*U3)/U1) < 0.000001 ) {
00527                         //this eigen vector is on a plane
00528                         //because any value of Z is acceptable                  
00529                         eigen_vec[i][2] = 1;
00530                         eigen_vec[i][1] = -( eigen_vec[i][2] * U4/U3);
00531                         eigen_vec[i][0] = (-RTR[1][0] * eigen_vec[i][1] - RTR[2][0]*eigen_vec[i][2]) / (RTR[0][0]-eigen_val[i]);                
00532                         
00533                         //normalize the vector
00534                         tmp = 1/sqrt( eigen_vec[i][0]*eigen_vec[i][0] + eigen_vec[i][1]*eigen_vec[i][1] + eigen_vec[i][2]*eigen_vec[i][2]);
00535                         eigen_vec[i][0] *= tmp;
00536                         eigen_vec[i][1] *= tmp;
00537                         eigen_vec[i][2] *= tmp;
00538                 } else {
00539                         //fprintf(stderr, "Weird error\n");
00540                         return 1;
00541                 }
00542         }       
00543         //eigen_vec[2] is the cross product of eigen_vec[0] eigen_vec[1]
00544         eigen_vec[2][0] = (eigen_vec[0][1]*eigen_vec[1][2] - eigen_vec[0][2]*eigen_vec[1][1]);
00545         eigen_vec[2][1] = (eigen_vec[0][2]*eigen_vec[1][0] - eigen_vec[0][0]*eigen_vec[1][2]);
00546         eigen_vec[2][2] = (eigen_vec[0][0]*eigen_vec[1][1] - eigen_vec[0][1]*eigen_vec[1][0]);
00547         
00548         double sigma[3] = {1,1,1};      
00549         double Rak[3][3];       
00550         for (j = 0; j < 3; j++) {
00551                 for (i = 0; i < 3; i++) {
00552                         Rak[j][i] = 0;
00553                         for (k = 0; k < 3; k++) {
00554                                 Rak[j][i] += R[j][k] * eigen_vec[i][k]; 
00555                         }
00556                 }
00557         }
00558         for (i=0;i<3;i++)
00559                 eigen_val[i]=sqrt(max_val*eigen_val[i]);        
00560         
00561         for (i=0;i<3;i++) {
00562                 for (j=0;j<3;j++) {
00563                         Rak[i][j]=0;
00564                         for (k=0;k<3;k++)
00565                                 Rak[i][j]+=(eigen_vec[k][i]*eigen_vec[k][j]*sigma[k]/eigen_val[k]);
00566                 }
00567         }
00568         for (i=0;i<3;i++){
00569                 for (j=0;j<3;j++) {
00570                         matrix[i][j]=0;
00571                         for (k=0;k<3;k++)
00572                                 matrix[i][j]+=(R[i][k]*Rak[k][j]);
00573                 }
00574         }               
00575         return 0;
00576 }
00577 
00578 
00579 
00580 char smCalcMinRmsdRotationTri( vec3 *vec_a, vec3 *vec_b, float matrix[3][3]) {
00581         double R[3][3], RT[3][3], RTR[3][3], eigen_val[3],
00582     eigen_vec[3][3] = { {0,0,0}, {0,0,0}, {0,0,0} }, b_mat[3][3];
00583         long n,i,j,k;
00584         double a, b, c, q, p, U1, U2, U3, U4, max_val, h,
00585                 i_val, j_val, k_val, L, M, N, P, tmp;
00586         
00587         //get the dot product from vec_a & vec_b
00588         
00589         vec3 cross_a, cross_b;
00590         
00591         smCrossProduct(vec_a[0], vec_a[1], cross_a);
00592         smCrossProduct(vec_b[0], vec_b[1], cross_b);
00593 
00594         
00595         for (i = 0; i < 3; i++) {
00596                 for (j = 0; j < 3; j++) {
00597                         R[i][j] = (vec_a[0][i] * vec_b[0][j]) + (vec_a[1][i] * vec_b[1][j]) + 
00598                         (vec_a[2][i] * vec_b[2][j]) + (cross_a[i] * cross_b[j]);
00599                         /*
00600                         R[i][j] = 0;
00601                         for (n = 0; n < len; n++) {
00602                                 R[i][j] += vec_a[n][i] * vec_b[n][j];
00603                         }
00604                          */
00605                 }
00606         }
00607         for (i = 0; i < 3; i++) {
00608                 for (j = 0; j < 3; j++) {
00609                         RT[j][i] = R[i][j]; 
00610                 }       
00611         }
00612         
00613         //max_val = 0;
00614         for (i = 0; i < 3; i++) {
00615                 for (j = 0; j < 3; j++) {
00616                         RTR[i][j] = 0;
00617                         for (k = 0; k < 3; k++) {
00618                                 RTR[i][j] += RT[k][i] * R[j][k];
00619                                 //if ( fabs(RTR[i][j]) > max_val ) 
00620                                 //      max_val = fabs(RTR[i][j]);
00621                         }
00622                 }
00623         }
00624         
00625         //for (i = 0; i < 3; i++) {
00626         //      for (j = 0; j < 3; j++) {
00627         //              RTR[i][j] /= max_val;
00628         //      }
00629         //}
00630         
00631         
00632         
00633         //find the co-effiecents for the eigen value cubic equation
00634         a = -(
00635                   RTR[0][0] + 
00636                   RTR[1][1] + 
00637                   RTR[2][2]
00638                   );
00639         b = -(
00640                   -(RTR[0][0]*RTR[2][2]) - 
00641                   (RTR[1][1]*RTR[2][2]) - 
00642                   (RTR[0][0]*RTR[1][1]) + 
00643                   (RTR[0][2]*RTR[2][0]) +
00644                   (RTR[1][0]*RTR[0][1]) +
00645                   (RTR[1][2]*RTR[2][1])
00646                   );
00647         
00648         c = -(
00649                   (RTR[0][0]*RTR[1][1]*RTR[2][2]) +
00650                   (RTR[2][0]*RTR[0][1]*RTR[1][2]) +
00651                   (RTR[1][0]*RTR[0][2]*RTR[2][1]) -
00652                   (RTR[0][2]*RTR[1][1]*RTR[2][0]) -
00653                   (RTR[0][1]*RTR[1][0]*RTR[2][2]) -
00654                   (RTR[0][0]*RTR[1][2]*RTR[2][1])
00655                   );
00656         
00657         //apply cubic equation to find the actual eigen values
00658         
00659         p = b - (pow(a,2.0)/ 3.0);
00660         q = c + (2.0*pow(a,3.0) - 9.0*a*b) / 27.0;
00661         
00662         h = (pow(q,2.0)/4.0) + (pow(p,3.0)/27.0);
00663         
00664         i_val = sqrt( (pow(q,2.0) / 4.0) - h );
00665         j_val = cbrt( i_val );
00666         
00667         k_val = acos( -(q/ (2.0*i_val)) );
00668         
00669         L = j_val * -1;
00670         
00671         M = cos(k_val/3.0);
00672         
00673         N = sqrt(3.0) * sin( k_val / 3.0 );
00674         
00675         
00676         P = (a/3.0 ) * -1;
00677         
00678         eigen_val[0] = 2 * j_val * cos(k_val/3.0) - (a/(3.0));
00679         eigen_val[1] = L * (M+N)+P;
00680         eigen_val[2] = L * (M-N)+P;
00681         
00682         
00683         //for each of the eigen values, determine the eigen vector
00684         
00685         for (i = 0; i < 3; i++) {
00686                 U1 = (RTR[1][1] - eigen_val[i]) - 
00687                 (RTR[0][1] * RTR[1][0])
00688                 /(RTR[0][0]-eigen_val[i]);
00689                 U2 = (RTR[2][1]) - 
00690                         (RTR[0][1] * RTR[2][0])
00691                         /(RTR[0][0]-eigen_val[i]);
00692                 U3 = (RTR[1][2]) - 
00693                         (RTR[0][2] * RTR[1][0])
00694                         /(RTR[0][0]-eigen_val[i]);
00695                 U4 =  (RTR[2][2] - eigen_val[i]) - 
00696                         (RTR[0][2] * RTR[2][0])
00697                         /(RTR[0][0]-eigen_val[i]);
00698                 
00699                 if ( fabs(U4 - (U2*U3)/U1) < 0.001 ) {
00700                         //this eigen vector is on a plane
00701                         //because any value of Z is acceptable
00702                         
00703                         eigen_vec[i][2] = 1;
00704                         eigen_vec[i][1] = -( eigen_vec[i][2] * U4/U3);
00705                         eigen_vec[i][0] = (-RTR[1][0] * eigen_vec[i][1] - RTR[2][0]*eigen_vec[i][2]) / (RTR[0][0]-eigen_val[i]);
00706                         
00707                         
00708                         //normalize the vector
00709                         tmp = 1/sqrt( eigen_vec[i][0]*eigen_vec[i][0] + eigen_vec[i][1]*eigen_vec[i][1] + eigen_vec[i][2]*eigen_vec[i][2]);
00710                         eigen_vec[i][0] *= tmp;
00711                         eigen_vec[i][1] *= tmp;
00712                         eigen_vec[i][2] *= tmp;
00713                 } else {
00714                         //fprintf(stderr, "Weird error\n");
00715                         return 1;
00716                 }
00717         }
00718         
00719         for (k = 0; k < 3; k++) {
00720                 for (i = 0; i < 3; i++) {
00721                         b_mat[k][i] = 0;
00722                         for (j = 0; j < 3; j++) {
00723                                 b_mat[k][i] += R[j][i] * eigen_vec[k][j];       
00724                         }
00725                         b_mat[k][i] /= sqrt( eigen_val[k]);
00726                 }
00727         }
00728         
00729         
00730         for (i = 0; i < 3; i++) {
00731                 for (j = 0; j < 3; j++) {
00732                         matrix[i][j] = 0;
00733                         for (k = 0; k < 3; k++) {
00734                                 matrix[i][j] += b_mat[k][i] * eigen_vec[k][j];          
00735                         }
00736                 }
00737         }
00738         
00739         for (i = 0; i < 3; i++) {
00740                 for (j = 0; j < 3; j++) {
00741                         //matrix[i][j] /= sqrt(max_val);                
00742                         //assert(!isnan(matrix[i][j]));
00743                         if ( isnan(matrix[i][j]) ) {
00744                                 return 1;
00745                         }
00746                 }
00747         } 
00748         return 0;
00749 }
00750 
00751 
00752 
00753 void smMoveMeanOrigin( vec3 *vec_a, int len_a ) {       
00754         vec3 mean = {0,0,0};
00755     for (int i = 0; i < len_a; i++) {
00756                 for (int j = 0; j < 3; j++) {
00757                         mean[j] += vec_a[i][j];
00758                 }       
00759     }
00760     for (int j = 0; j < 3; j++) {
00761                 mean[j] /= (float)len_a;
00762     }
00763     for (int i = 0; i < len_a; i++) {
00764                 for (int j = 0; j < 3; j++) {
00765                         vec_a[i][j] -= mean[j];
00766                 }
00767     }           
00768 }
00769 
00770 void smMoveMeanOrigin( vec3 *vec_a, int len_a, vec3 *vec_b ) {
00771         vec3 mean = {0,0,0};
00772     for (int i = 0; i < len_a; i++) {
00773                 for (int j = 0; j < 3; j++) {
00774                         mean[j] += vec_a[i][j];
00775                 }       
00776     }
00777     for (int j = 0; j < 3; j++) {
00778                 mean[j] /= (float)len_a;
00779     }
00780         for (int i = 0; i < len_a; i++) {
00781                 for (int j = 0; j < 3; j++) {
00782                         vec_b[i][j] = vec_a[i][j] - mean[j];
00783                 }
00784     }   
00785 }
00786 
00787 
00788 void smCalcMeanOrigin( vec3 *vec_a, int len_a, vec3 trans ) {   
00789         vec3 mean = {0,0,0};
00790     for (int i = 0; i < len_a; i++) {
00791                 for (int j = 0; j < 3; j++) {
00792                         mean[j] += vec_a[i][j];
00793                 }       
00794     }
00795     for (int j = 0; j < 3; j++) {
00796                 mean[j] /= (float)len_a;
00797     }
00798         trans[0] = -mean[0];
00799         trans[1] = -mean[1];
00800         trans[2] = -mean[2];    
00801 }
00802 
00803 char smMoveMinRmsd( vec3 *vec_a, vec3 *vec_b, int len ) {
00804   mat3 matrix;
00805   if ( smCalcMinRmsdRotation( vec_a, vec_b, len, matrix ) ) {
00806     return 1;
00807   }
00808   smMultVec( vec_a, matrix, len );
00809   return 0;
00810 }
00811 
00812 
00813 float smCalcRmsd( vec3 *vec_a, vec3 *vec_b, int len ) {
00814         double total = 0;
00815         for (int i = 0; i < len; i++) {
00816                 for (int j = 0; j < 3; j++) {
00817                         total += pow(vec_a[i][j] - vec_b[i][j], 2);
00818                 }       
00819         }
00820         return sqrt( total / (double) len );    
00821 }
00822 
00823 float smCalcInterRmsd( vec3 *vec_a, vec3 *vec_b, int len ) {
00824         double total = 0, count = 0;
00825         for (int i = 0; i < len; i++) {
00826                 for ( int j = i+1; j < len; j++ ) {
00827                         float dist_a = smDistance( vec_a[i], vec_a[j] );
00828                         float dist_b = smDistance( vec_b[i], vec_b[j] );
00829                         total += pow(dist_a - dist_b, 2);
00830                         count++;
00831                 }
00832         }
00833         return sqrt( total / count );   
00834 }
00835 
00836 
00837 float smCalcFrobeniusNorm( float matrix_a[3][3], float matrix_b[3][3] ) {
00838         long  i,j;
00839         float  total = 0, tmp_matrix[3][3];
00840         
00841         for (i = 0; i < 3; i++) {
00842                 for (j = 0; j < 3; j++) {
00843                         tmp_matrix[i][j] = matrix_a[i][j] - matrix_b[i][j];     
00844                 }
00845         }
00846         for (i = 0; i < 3; i++) {
00847                 for (j = 0; j < 3; j++) {
00848                         total += tmp_matrix[i][j] * tmp_matrix[i][j];           
00849                 }
00850         }
00851         return sqrt(total);
00852         
00853 }
00854 
00855 
00856 
00857 

Generated on Wed Apr 11 16:50:50 2007 for open_prospect by  doxygen 1.4.6