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
Post a Comment