Rotations using quaternions

  • Nobody/Anonymous

    I tried your piece of code out to rotate a vector using a quaternion in Matlab, from the page:

    However, it was not working.  I worked out the math and I think that for each of the terms involving 2*w in your code, the sign is the opposite of what it should be.  I tried the following version of code out and it seems to function correctly:

    p2.x = w*w*p1.x + x*x*p1.x - y*y*p1.x - z*z*p1.x + 2*(w*z*p1.y - w*y*p1.z + x*y*p1.y + x*z*p1.z);
    p2.y = w*w*p1.y - x*x*p1.y + y*y*p1.y - z*z*p1.y + 2*(w*x*p1.z - w*z*p1.x + x*y*p1.x + y*z*p1.z);
    p2.z = w*w*p1.z - x*x*p1.z - y*y*p1.z + z*z*p1.z + 2*(w*y*p1.x - w*x*p1.y + x*z*p1.x + y*z*p1.y);

    • Martin Baker

      Martin Baker - 2003-07-24

      Can you see where the derivation has gone wrong, I had a look but I could not find the error.

      The problem is that the code cross checks with the quaternion to matrix conversion also example 1. Although its possible that Ive made the same error in the derivation of these, if so Im not detached enough to spot the error?


      • Nobody/Anonymous

        Upon further inspection, realized I was computing the rotation from q'pq rather than qpq'.  I think the ordering just determines whether the rotation is clockwise or counter-clockwise.

    • Michaele Norel

      Michaele Norel - 2003-07-25

      Hi Martin!

      I found on the page:
      "Quaternions can represent rotations, but unlike matrices, quaternions cannot represent scaling or translation."

      In general quaternion can keep scale. If it keep scale, it is not unit.
      To get rotation matrix we can use:
      Matrix =  [ w2 + x2 - y2 - z2       2xy - 2wz           2xz + 2wy
                      2xy + 2wz       w2 - x2 + y2 - z2       2yz - 2wx
                      2xz - 2wy           2yz + 2wx       w2 - x2 - y2 + z2 ]

      It give the scaled rotation matrix with a scale that equal norm of quaternion.

      Corresponding conversion from matrix to quat , i still didn't found.


      • Nobody/Anonymous

        Yes, I agree with minor logic. But you see, rotation matrix with a scale that equal norm of quaternions.. If you used the (p-o) equasion efficiently, then you would find a logical lead into pi from the square route of 6.

    • Martin Baker

      Martin Baker - 2003-07-26

      Hi minorlogic,

      Ill have to think about this!

      When we translate points using a quaternion we use:
      PointOut = q * PointIn *q

      But I think this assumes that q is normalised? Im not sure about this, can you confirm? This is what I used to derive matrix so the matrix to quaternion conversion assumes a normalised quaternion? I'm not sure what assumptions the gamedev paper makes, but since it gets the same result, it may make the same assumptions?

      I think that if we want to translate points using a non normalised quaternion we would have to use:
      PointOut = q * PointIn *q^-1

      I have not done the algebra but I think this may introduce an extra division by (w*w+x*x+y*y+z*z) term?

      I guess the way to find the effect of a scaling factor might be to take both,
      q1 = (w,x,y,z)
      q2 = (w*c,x*c,y*c,z*c)

      and see what this does to pointOut, so if we take:
      PointOut1 = q1 * PointIn *q1^-1
      PointOut2 = q2 * PointIn *q2^-1

      Will PointOut2 = PointOut1 *c ???

      In other words does multiplying the elements of the quaternion by a constant multiply the translated points by the same constant?

      This issue of mixing rotation and scaling makes me think of Clifford algebra. 3d multivectors seem to be a superset of quaternions, so I am trying to learn more about Clifford algebra, I have put some papers by Alfred Differ on the website and linked to them from:


    • Nobody/Anonymous

      >Will PointOut2 = PointOut1 *c ???


        PointOut2 = PointOut1 *c*c

      and i think it can be very usefull .

      We can get a very usefull conversion from nonunit quat to matrix.

      We need just scale matrix by inverse of quat norm(1/q.norm()).

      quaternion_to_matrix_keep_scale(quaternion q )
      float n = q.norm();   

      m00  = n - 2 * ( yy + zz );
      m01  =     2 * ( xy - zw );
      m02  =     2 * ( xz + yw );

      we get a matrix scaled by norm() // xx+yy+zz+ww


      quaternion_to_matrix_rotation_nonunit(quaternion q )
        float s = 2.0/q.norm();//additional 4 mul 3 add, 1 div

        float xs = x*s;
        float ys = x*s;

      m00  = 1 - y*ys + z*zs;
      m01  =     x*ys - z*ws;
      m02  =     x*zs + y*ws;


      So to get (as example ) rotation matrix from angle, we can use 1 sqrt, CAUSE WE NEEd no normalize quat

    • Martin Baker

      Martin Baker - 2003-07-31


      Thanks very much for this, I never realised before that its possible to use a single quaternion to both rotate and to scale equally in all directions.

      I will update the web page and have a think about way to make use of this.




Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

JavaScript is required for this form.

No, thanks