Quaternion coordinate axis change

Started by
1 comment, last by apatriarca 11 years, 6 months ago
Hi guys, I’m having problems with an animation that uses quaternions. The problem is that the bones are given to me in the form of quaternions such that:
1) The system is right handed.
2) In particular the example of bone I want to resolve is this:
Hueso.PNGAxis.PNG

In my game the corresponding bone frame of reference is left handed. In particular it is:
Unity.PNGAxis2.PNG

So the map would be:

from = +Y along arm, +X right, +Z forward
to = -X along arm, -Z right, -Y forward

In resume my problems are:
* The quaternion of the rotation is in a left hand system
* My system is right handed and with different axis


Watching an example I found that the change in the quaternion seems to be:
Where originalRotation is the rotation in the right hand system
myRotation is the rotation in my axis

Quaternion myRotation = new Quaternion(-originalRotation.y, originalRotation.z, originalRotation.x, originalRotation.w);


This seems to work... but I don’t know how to get there.... it is a change of frame of reference with quaternion with a handness change...
Thanks in avance
Advertisement
I guess you're an artist?
If so, you should not care. The programmer writing the filter should.
But I suppose that's you anyway.
I converted the quaternion to a matrix and converted the matrix. Not quite The Right Thing but keeps the whole point of encoding a rigid transform, and that was all that I needed.

Previously "Krohm"

Since you asked, you may be interested in reading how to derive the quaternion corresponding to a different orthonormal reference frame. I assume you know that each rotation in 3D can be represented as a rotation or some angle theta around an axis axis. A unit quaternion representing such rotation is defined as

cos(theta/2) + sin(theta/2)*axis.

In this post I will not use the quaternion representation, but the angle-axis representation with the Rodrigues' rotation formula

R(theta, axis)*v = cos(theta)*v + sin(theta)*cross(axis, v) + (1 - cos(theta))*dot(axis, v)*axis.

Let M be the orthogonal matrix of the change of coordinate from the orthonormal reference frame A to the orthonormal reference frame B, R(thetaA, axisA) the rotation in the reference frame A and R(thetaB, axisB) the corresponding rotation in the reference frame B. Then the rotations should satisfy

R(thetaB, axisB)*M*v = M*R(thetaA, axisA)*v

Since R(thetaA, axisA)*axisA = axisA, then we should have R(thetaB, axisB)*M*axisA = M*R(thetaA, axisA)*axisA = M*axisA. Then M*axisA should be parallel to axisB. In particular, it will be equal to +axisB or -axisB. Let S represent this sign.

Using the Rodrigues' rotation formula we obtain

cos(thetaB)*M*v + sin(thetaB)*cross(axisB, M*v) + (1 - cos(thetaB))*dot(axisB, M*v)*axisB = M*( cos(thetaA)*v + sin(thetaA)*cross(axisA, v) + (1 - cos(thetaA))*dot(axisA, v)*axisA )

We should now clearly have cos(thetaB) = cos(thetaA) which implies (in [-pi, pi]) abs(thetaB) = abs(thetaA). We also have that M*cross(axisA, v) = det(M)*cross(M*axisA, M*v) = S*det(M)*cross(axisB, M*v). Thus, sin(thetaB) = sin(thetaA)*S*det(M). Finally, we have

dot(axisB, M*v)*axisB = dot(axisA, v)*M*axisA = S*dot(M*axisA, M*v)*axisB = (axisB, M*v)*axisB.

We can thus choose S to be either +1 or -1 and then use the equation sin(thetaB) = sin(thetaA)*S*det(M) to fix thetaB accordingly. For example, if we choose S=-1, then sin(thetaA) = sin(thetaB) in your case which implies thetaA = thetaB. If S=+1 was chosen, then sin(thetaA) = -sin(thetaB) and thetaA = -thetaB.

This topic is closed to new replies.

Advertisement