c++ - rotation matrix to quaternion (and back) what is wrong? -


i copied code conversion of 3d roation matrix quaternions , back. same code used in jmonkey (i rewrote c++ class). however, not work (at least not expect.)

e.g. made test:

matrix (a,b,c):   : 0.707107 0.000000 0.707107  b : 0.000000 -1.000000 0.000000  c : -0.707107 0.000000 0.707107   >>> ortonormality:   a.a b.b c.c  1.000000 1.000000 1.000000   a.b a.c b.c  0.000000 0.000000 0.000000   >>> matrix -> quat  quat: 0.000000 0.594604 0.000000 0.594604  norm(quat) 0.707107    >>> quat -> matrix   matrix (a,b,c): a: 0.000000 0.000000 1.000000  b: 0.000000 1.000000 0.000000  c: -1.000000 0.000000 0.000000  

i think problem in matrix -> quat because have used quat -> matrix procedure before, , working fine. strange quaternion made orthonormal matrix not unitary.

the matrix -> quat procedure

inline void frommatrix( type m00, type m01, type m02,    type m10, type m11, type m12,        type m20, type m21, type m22) {     // use graphics gems code,      // ftp://ftp.cis.upenn.edu/pub/graphics/shoemake/quatut.ps.z     type t = m00 + m11 + m22;     // protect division s ensuring s>=1     if (t >= 0) { // w         type s = sqrt(t + 1);         w = 0.5 * s;         s = 0.5 / s;                          x = (m21 - m12) * s;         y = (m02 - m20) * s;         z = (m10 - m01) * s;     } else if ((m00 > m11) && (m00 > m22)) { // x         type s = sqrt(1 + m00 - m11 - m22);          x = s * 0.5;          s = 0.5 / s;         y = (m10 + m01) * s;         z = (m02 + m20) * s;         w = (m21 - m12) * s;     } else if (m11 > m22) { // y         type s = sqrt(1 + m11 - m00 - m22);          y = s * 0.5;          s = 0.5 / s;         x = (m10 + m01) * s;         z = (m21 + m12) * s;         w = (m02 - m20) * s;     } else { // z         type s = sqrt(1 + m22 - m00 - m11);          z = s * 0.5;          s = 0.5 / s;         x = (m02 + m20) * s;         y = (m21 + m12) * s;         w = (m10 - m01) * s;     } } 

the quat -> matrix procedure

inline void tomatrix( mat& result) const {         type r2 = w*w + x*x + y*y + z*z;         //type s  = (r2 > 0) ? 2d / r2 : 0;         type s  = 2 / r2;         // compute xs/ys/zs first save 6 multiplications, since xs/ys/zs         // used 2-4 times each.         type xs = x * s;  type ys = y * s;  type zs = z * s;         type xx = x * xs; type xy = x * ys; type xz = x * zs;         type xw = w * xs; type yy = y * ys; type yz = y * zs;         type yw = w * ys; type zz = z * zs; type zw = w * zs;         // using s=2/norm (instead of 1/norm) saves 9 multiplications 2 here         result.xx = 1 - (yy + zz);         result.xy =     (xy - zw);         result.xz =     (xz + yw);         result.yx =     (xy + zw);         result.yy = 1 - (xx + zz);         result.yz =     (yz - xw);         result.zx =     (xz - yw);         result.zy =     (yz + xw);         result.zz = 1 - (xx + yy); }; 

sorry type, vec, mat, quat part of class tepmpltes... should replaced double, vec3d, mat3d, quat3d or float, vec3f, mat3f, quat3f.

edit:

i checked if same behaviour jmonkey directly (in case made bug in java c++ conversion ). , - using code:

    matrix3f min  = new matrix3f( 0.707107f, 0.000000f, 0.707107f, 0.000000f, -1.000000f, 0.000000f, -0.707107f,  0.000000f,  0.707107f  );     matrix3f mout = new matrix3f( );     quaternion q = new quaternion();     q.fromrotationmatrix(min);     system.out.println( q.getx()+" "+q.gety()+" "+q.getz()+" "+q.getw() );     q.torotationmatrix(mout);     system.out.println( mout.get(0,0) +" "+mout.get(0,1)+" "+mout.get(0,2) );     system.out.println( mout.get(1,0) +" "+mout.get(1,1)+" "+mout.get(1,2) );     system.out.println( mout.get(2,0) +" "+mout.get(2,1)+" "+mout.get(2,2) ); 

your matrix:

matrix (a,b,c):   : 0.707107 0.000000 0.707107  b : 0.000000 -1.000000 0.000000  c : -0.707107 0.000000 0.707107 

is orthogonal not rotation matrix. rotation matrix has determinant 1; matrix has determinant -1 , improper rotation.

i think code correct , issue in data. try real rotation matrix.


Comments

Popular posts from this blog

angularjs - ADAL JS Angular- WebAPI add a new role claim to the token -

php - CakePHP HttpSockets send array of paramms -

node.js - Using Node without global install -