PolGraphic
PolGraphic

Reputation: 3364

Convert quaternion from right-handed to left-handed coordinate system

I my 3d program, the rotation of object is represented by the quaternion like [0.130526, 0.0, 0.0, 0.991445]. The program works with right-handed coordinate system with the Z axis pointing up (like in 3ds max):

enter image description here

On the other hand, my application use left-handed coordinate system and the Y axis is up:

enter image description here

How can I transform my quaternion from one coordinate system to another, with the respect for which axis is up?

Upvotes: 13

Views: 23326

Answers (3)

Řrřola
Řrřola

Reputation: 6307

Geometric algebra solution just for fun.

I'll write uv for the geometric product of vectors u and v.
It's commutative for parallel vectors: uv = vu when uv,
anticommutative for orthogonal vectors: uv = −vu when uv,
and associative: (uv)w = u(vw) = uvw.
Furthermore, uu = |u|² (the square of the length).

Let (x, y, z) be the old right-handed basis.
Vectors in the basis are orthogonal, so xy = −yx, yz = −zy, zx = −xz,
and have length 1, so xx = yy = zz = 1.

The quaternion basis (1, i, j, k) corresponds to the multivector basis (1, zy, xz, yx).
You can check that all the quaternion identities work. For example:

  • ij = zyxz = −zyzx = zzyx = yx = k,
  • k² = yxyx = −yyxx = −xx = −1,
  • ijk = k² = −1.

A quaternion in the old basis can be written as s + b⋅zy + c⋅xz + d⋅yx.
A quaternion in the new basis can be written as S + B⋅yz + C⋅xy + D⋅zx. (We've swapped y and z.)

Solving for the new coefficients, we get S=s, B=−b, C=−d and D=−c.

There are two conventions for writing quaternion coefficients: [s, b,c,d] and [b,c,d, s].

  • [s=0.130526, b=0, c=0, d=0.991445] transforms to [S=0.130526, B=0, C=-0.991445, D=0].
  • [b=0.130526, c=0, d=0, s=0.991445] transforms to [B=-0.130526, C=0, D=0, S=0.991445].

Upvotes: 2

Paul Du Bois
Paul Du Bois

Reputation: 2171

This is a condensed version of an answer to a slightly different question.

The problem you ask about arises even if the two coordinate systems are same-handed; it turns out that handedness flips don't make the problem significantly harder. Here is how to do it in general. To change the basis of a quaternion, say from ROS (right-handed, Z up) to Unity (left-handed, Y up):

mat3x3 ros_to_unity = /* construct this by hand by mapping input axes to output axes */;
mat3x3 unity_to_ros = ros_to_unity.inverse();
quat q_ros = ...;
mat3x3 m_unity = ros_to_unity * mat3x3(q_ros) * unity_to_ros;
quat q_unity = mat_to_quat(m_unity);

Lines 1-4 are simply the method of https://stackoverflow.com/a/39519079/194921: "How do you perform a change-of-basis on a matrix?"

Line 5 is interesting; not all matrices convert to quats, but if ros_to_unity is correct, then this conversion will succeed.

Note that this will give you a correct result, but it goes through a lot of work -- conversion to and from a matrix, some multiplies, an inversion. But you can examine its results and then write a special-case version that rearranges or flips axes, like the one aka.nice derived.

Upvotes: 4

aka.nice
aka.nice

Reputation: 9382

A rotation of angle x around axis (u,v,w) can be represented by quaternion with real part cos(x/2) and unreal part sin(x/2)*(u,v,w).

If axis coordinates are (u,v,w) in original trihedron, they will be (u,w,v) in your trihedron.

Thus if original quaternion was (a,b,c,d) - a+ib+jc+kd - the quaternion must be transformed to (a,b,d,c) in your trihedron.

EDIT

But because your trihedron is left handed, the angle also has to be reversed, so the same rotation can finally be expressed by the quaternion (a,-b,-d,-c) in your trihedron.

Upvotes: 15

Related Questions