•      Sign In
• Create Account

## Left-Handed Euler Rotation Matrices

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

6 replies to this topic

### #1L. Spiro  Members

24827
Like
0Likes
Like

Posted 30 May 2013 - 11:06 AM

I am trying to emulate the FBX system of determining an object’s local transform (described here).
For simplification, I only need to worry about the local Euler rotations of the object—the scale, pivots, pre-rotate, post-rotate, etc., are all “identity” and do not contribute to the result for my test work.

That means I only have to take an X-rotation matrix, Y-rotation matrix, and Z-rotation matrix and combine them in that order (because I am using row-major matrices whereas they are using column-major matrices).

When I actually construct these 3 matrices and combine them in that order, it works fine.  Code for the way I construct them (only upper 3×3 shown):

MatrixRotationX( _tType _tAngle ) {
LSREAL fS;
LSREAL fC;
CMathLib::SinCos( static_cast<LSREAL>(_tAngle), fS, fC );
_11 = 1.0;
_12 = 0.0;
_13 = 0.0;

_21 = 0.0;
_22 = fC;
_23 = fS;

_31 = 0.0;
_32 = -fS;
_33 = fC;
}
MatrixRotationY( _tType _tAngle ) {
LSREAL fS;
LSREAL fC;
CMathLib::SinCos( static_cast<LSREAL>(_tAngle), fS, fC );
_11 = fC;
_12 = 0.0;
_13 = -fS;

_21 = 0.0;
_22 = 1.0;
_23 = 0.0;

_31 = fS;
_32 = 0.0;
_33 = fC;
}
MatrixRotationZ( _tType _tAngle ) {
LSREAL fS;
LSREAL fC;
CMathLib::SinCos( static_cast<LSREAL>(_tAngle), fS, fC );
_11 = fC;
_12 = fS;
_13 = 0.0;

_21 = -fS;
_22 = fC;
_23 = 0.0;

_31 = 0.0;
_32 = 0.0;
_33 = 1.0;
}
According to this, this is a left-handed system that has been transposed for my row-major matrices (theirs are column-major).  My assignments are grouped by rows, and my row [_11, _12, _13] matches their first column except that the sign of the sine’s are reversed, making it left-handed (I guess?).

In any case, if I use these to manually combine the XYZ Euler rotations from the FBX data the result is correct.
But I don’t want to construct 3 matrices and multiply them together when I know there is a way to get the result directly.

So I checked here to get some direct conversions.
My code for their Tait-Bryan XYZ set follows (exactly the same but transposed into row-major):
MatrixRotationXYZ( _tType _tX, _tType _tY, _tType _tZ ) {
LSREAL fS1, fC1;
CMathLib::SinCos( static_cast<LSREAL>(_tX), fS1, fC1 );

LSREAL fS2, fC2;
CMathLib::SinCos( static_cast<LSREAL>(_tY), fS2, fC2 );

LSREAL fS3, fC3;
CMathLib::SinCos( static_cast<LSREAL>(_tZ), fS3, fC3 );

_11 = fC2 * fC3;
_12 = fC1 * fS3 + fC3 * fS1 * fS2;
_13 = fS1 * fS3 - fC1 * fC3 * fS2;

_21 = -fC2 * fS3;
_22 = fC1 * fC3 - fS1 * fS2 * fS3;
_23 = fC3 * fS1 + fC1 * fS2 * fS3;

_31 = fS2;
_32 = -fC2 * fS1;
_33 = fC1 * fC2;
}
Obviously, this is not going to work, as it is right-handed and transposing is not enough.
How do I make this left-handed? I need at least this one, but best would be a table of all combinations (YZX, XZY, ZYX, etc., as on Wikipedia).

Thank you,
L. Spiro

### #2RobTheBloke  Members

2536
Like
0Likes
Like

Posted 30 May 2013 - 02:09 PM

M' = ScaleMatrix(1, 1, -1) * M * ScaleMatrix(1, 1, -1)

Edited by RobTheBloke, 30 May 2013 - 02:21 PM.

### #3L. Spiro  Members

24827
Like
0Likes
Like

Posted 31 May 2013 - 06:50 AM

I tried it; the model vanishes completely.  Besides I am specifically trying to avoid any matrix multiplication.

L. Spiro

### #4Paradigm Shifter  Members

5832
Like
1Likes
Like

Posted 31 May 2013 - 07:07 AM

I did the multiplication and got

_11 = c2c3

_12 = c2s3

_13 = -s2

_21 = s1s2c3 - c1s3

_22 = s1s2s3 + c1c3

_23 = s1c2

_31 = c1s2c3 + s1s3

_32 = c1s2s3 - s1c3

_33 = c1c2

I may have made a mistake though. Just multiply the matrices together...

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

### #5L. Spiro  Members

24827
Like
0Likes
Like

Posted 31 May 2013 - 07:19 AM

Doing the math by hand is my plan for the rest of them too. I’m planning to make some temporary code that will print the whole multiplication process for each matrix to make it easy and accurate.

But first I will try yours and get back.

L. Spiro

[EDIT]
Yours works.
I will do the rest by myself and post the results later for anyone who needs them all.
[/EDIT]

Edited by L. Spiro, 31 May 2013 - 08:08 AM.

### #6Paradigm Shifter  Members

5832
Like
1Likes
Like

Posted 31 May 2013 - 12:00 PM

You might want to remember that when dealing with products of transposed matrices, the following formula applies:

(AB)T = BT * AT

EDIT: Proof here: http://www.proofwiki.org/wiki/Transpose_of_Matrix_Product

And for multiple products of transposes

(A1A2...An-1An)T = AnT * An-1T * ... * A2T * A1T

Which is very similar to the product of inverses formula too (replace AT with A-1). The inverse formula is trivial to prove.

EDIT2: So, since your X, Y, Z rotation matrices are transposed, you should find that XTYTZT = (ZYX)T

i.e. your XYZ rotation matrix will be the other library's ZYX rotation matrix, transposed.

Edited by Paradigm Shifter, 31 May 2013 - 02:29 PM.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

### #7L. Spiro  Members

24827
Like
0Likes
Like

Posted 10 June 2013 - 06:37 PM

I didn’t think of it that way.

I hadn’t had time to get around to my method of printing them out and simplifying due to health issues, so this will definitely save me some time.  Thank you.

L. Spiro

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.