## Rotations using quaternions document.SUBSCRIPTION_OPTIONS = { "thing": "thread", "subscribed": false, "url": "subscribe", "icon": { "css": "fa fa-envelope-o" } };

2003-07-24
2004-02-24
• Nobody/Anonymous - 2003-07-24

I tried your piece of code out to rotate a vector using a quaternion in Matlab, from the page:
http://www.martinb.com/maths/algebra/realNormedAlgebra/quaternions/transforms/index.htm

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 - 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?

Martin

• Nobody/Anonymous - 2003-07-24

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 - 2003-07-25

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:
http://www.gamedev.net/reference/articles/article1095.asp
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.

minorlogic

• Nobody/Anonymous - 2004-02-24

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 - 2003-07-26

Hi minorlogic,

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)
and
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
and
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:
http://www.martinb.com/maths/algebra/clifford/index.htm

Martin

• Nobody/Anonymous - 2003-07-30

>Will PointOut2 = PointOut1 *c ???

no,

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 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 - 2003-07-31

minorlogic,

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.

Thanks,

Martin