title: Converting quaternion to matrix and vice versa should have the same transformation
body: <p>Am I wrong on assuming that by arbitrary converting from Quaternion to Matrix of Vecmath classes should remain the same transformation to a vector/point?</p>
  
  <p>Here is my test script. It just loops around printing the rotated vector, testing the result and converting quaternion to matrix and vice versa.</p>
  
  <pre><code>public class Test {
  
      public static Vector3d rotateVector( Quat4d q, Vector3d v )
      {
          Quat4d w = new Quat4d();
          w.x = v.x;
          w.y = v.y;
          w.z = v.z;
          w.w = 0;
  
          Quat4d qTmp = new Quat4d();
  
          // q * w * q^-1
  
          qTmp.mul( q, w );
          qTmp.mulInverse( q );
  
          return new Vector3d( qTmp.x, qTmp.y, qTmp.z );
      }
  
      public static Vector3d rotateVector( Matrix4d m, Vector3d v )
      {
          Point3d vp = new Point3d( v );
  
          m.transform( vp );
  
          return new Vector3d( vp );
      }
  
      public static final double EPS = 0.00000001;
  
      public static void main( String[] args )
      {
          Quat4d q = new Quat4d();
          q.set( new AxisAngle4d( new Vector3d( 1, 0, -1 ), Math.PI ) ); // same as rotation x 90°, y 90°, z -90° in static frame
  
          Matrix4d m = new Matrix4d();
  
          Vector3d v = new Vector3d( 1, 2, 3 );
  
          Vector3d vResult = new Vector3d( -3, -2, -1 );
  
          String rotMethod = "";
  
          for( int i = 0; i &lt; 4; i++ )
          {
              rotMethod += "q";
              Vector3d vq = rotateVector( q, v );
              System.out.println( rotMethod + ": " + vq + " ==&gt; " + vResult.epsilonEquals( vq, EPS ) );
  
              m.set( q );
  
              rotMethod += "m";
              Vector3d vm = rotateVector( m, v );
              System.out.println( rotMethod + ": " + vm + " ==&gt; " + vResult.epsilonEquals( vm, EPS ) );
  
              q.set( m );
          }
      }
  }
  </code></pre>
  
  <p>Here is the output. First quaternionen and first matrix are doing ok. But then they drift off and converge to a somewhat mirrowed point.</p>
  
  <pre><code>q: (-3.0, -2.0000000000000004, -1.0) ==&gt; true
  qm: (-2.9999999999999987, -1.9999999999999993, -0.9999999999999989) ==&gt; true
  qmq: (1.4421707565920456, 0.2675892211829013, 3.4421707565920463) ==&gt; false
  qmqm: (1.0000000000000002, 1.9999999999999998, 3.0) ==&gt; false
  qmqmq: (1.0, 1.9999999999999996, 3.0) ==&gt; false
  qmqmqm: (1.0000000000000002, 1.9999999999999998, 3.0) ==&gt; false
  qmqmqmq: (1.0, 1.9999999999999996, 3.0) ==&gt; false
  qmqmqmqm: (1.0000000000000002, 1.9999999999999998, 3.0) ==&gt; false
  </code></pre>
  
  <p>Thanks in advance for your help and time.</p>
  
  <hr>
  
  <p><strong>Edit:</strong> Workaround</p>
  
  <p>Every Matrix to Quaternion conversion which I could find in the web were unstable with my test script like the vecmath library.</p>
  
  <p>Following implementation were tested: </p>
  
  <ul>
  <li><a href="http://www.lfd.uci.edu/~gohlke/code/transformations.c.html" rel="nofollow">http://www.lfd.uci.edu/~gohlke/code/transformations.c.html</a></li>
  <li><a href="http://www.cg.info.hiroshima-cu.ac.jp/~miyazaki/knowledge/teche52.html" rel="nofollow">http://www.cg.info.hiroshima-cu.ac.jp/~miyazaki/knowledge/teche52.html</a></li>
  <li><a href="http://www.thetenthplanet.de/archives/1994" rel="nofollow">http://www.thetenthplanet.de/archives/1994</a></li>
  </ul>
  
  <p>A workaround with <strong>Matrix -> Euler -> Quaternion</strong> provides the expected results.
  I fused the implementation of both conversion from <a href="http://www.lfd.uci.edu/~gohlke/code/transformations.py.html" rel="nofollow">Christoph Gohlke</a>.</p>
  
  <pre><code>public static void setQuatFromMatrix( Quat4d quat, Matrix4d mat )
  {
      double az, ay, ax;
      double ai, aj, ak;
      double si, sj, sk;
      double ci, cj, ck;
      double cy, cc, cs, sc, ss;
  
      cy = Math.sqrt( mat.m00 * mat.m00 + mat.m10 * mat.m10 );
  
      if( cy &gt; MathUtil.EPS )
      {
          ax = Math.atan2( mat.m21, mat.m22 );
          ay = Math.atan2( -mat.m20, cy );
          az = Math.atan2( mat.m10, mat.m00 );
      }
      else
      {
          ax = Math.atan2( -mat.m12, mat.m11 );
          ay = Math.atan2( -mat.m20, cy );
          az = 0.0;
      }
  
      ai = ax / 2.0;
      aj = ay / 2.0;
      ak = az / 2.0;
  
      ci = Math.cos( ai );
      si = Math.sin( ai );
      cj = Math.cos( aj );
      sj = Math.sin( aj );
      ck = Math.cos( ak );
      sk = Math.sin( ak );
      cc = ci * ck;
      cs = ci * sk;
      sc = si * ck;
      ss = si * sk;
  
      quat.x = cj * sc - sj * cs;
      quat.y = cj * ss + sj * cc;
      quat.z = cj * cs - sj * sc;
      quat.w = cj * cc + sj * ss;
  }
  </code></pre>
  
  <p>I didn't optimize it because I can't figure how but it works for me. Here is the output:</p>
  
  <pre><code>q: (-3.0, -2.0000000000000004, -1.0) ==&gt; true
  qm: (-2.9999999999999987, -1.9999999999999993, -0.9999999999999989) ==&gt; true
  qmq: (-2.9999999999999996, -2.0000000000000004, -1.0000000000000009) ==&gt; true
  qmqm: (-2.9999999999999996, -2.0000000000000004, -1.0000000000000007) ==&gt; true
  qmqmq: (-2.9999999999999996, -2.0000000000000004, -1.0000000000000009) ==&gt; true
  qmqmqm: (-2.9999999999999996, -2.0000000000000004, -1.0000000000000007) ==&gt; true
  qmqmqmq: (-2.9999999999999996, -2.0000000000000004, -1.0000000000000009) ==&gt; true
  qmqmqmqm: (-2.9999999999999996, -2.0000000000000004, -1.0000000000000007) ==&gt; true
  </code></pre>