• Advertisement
Sign in to follow this  

Left-Handed Euler Rotation Matrices

This topic is 1687 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
Advertisement

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

 

 

L. Spiro

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement