Yet Again: Matrix from right-handed to left-handed system

Started by
4 comments, last by Kuroyume0161 16 years, 2 months ago
I need to convert a right-handed matrix to a left-handed matrix. This is for a coordinate system transformation not points, projection, so on. I've tried every supposed way to do this and still the results are rotations that are 90d or 180d out from what they should be on occasion. Translations and scales are always simple and correct. I'm going to provide as much information as possible in order that someone might be capable of verifying the veracity of a methodology. So, here's an input right-handed matrix (one that seems to be flipped in the Y-axis (?) when converted): -0.0312836 -0.00783613 -0.013012 0 (X-Axis Basis) -0.012188 0.0731294 -0.0147378 0 (Y-Axis Basis) -0.0297495 0.00843272 0.0664458 0 (Z-Axis Basis) 0.104637 0.507761 -0.0222363 1 (translation: x,y,z) The bases appear to be correct and correspond to tests (I don't have any documentation for these matrices - and this is all I have to work with, a matrix). It is wholly possible that the Bases are columnar instead of rows (?) - doesn't appear to be the case. The matrix corresponds to these transformation values (x y z): Translate: 0.104637 0.507761 -0.0222363 Scale: 0.03478 0.07559 0.07329 Rotation: 167.867d 21.973d -165.938d The rotations in the matrix come from ordered Euler rotations. Again, I cannot verify the rotation order but am assuming YXZ from the only clue available in the source application. You are probably already saying, "But the homogeneous 'vector' isn't a row along the bottom, it's a column along the right." Yes. And it is assured that the source system is right-handed (x to the right, y upward, z out of the screen). So, there are several methods people mention to convert from this to left-handed: simply negate certain elements, use a transpose and similarity matrices (which is what I'm currently using). The target system uses a left-handed coordinate system and premultiplication of matrices. That is, if you want rotation like XYZ, you do this: Matrix m = MatrixRotZ(gamma)*MatrixRotY(beta)*MatrixRotX(alpha); There really isn't a 'matrix' to show you. The elements are stored in four 3-vectors: v1, v2, v3, off (X-Axis basis, Y-Axis basis, Z-Axis basis, translation). You can see that shoving the input matrix into this matrix isn't rocket science. Notice that the homogeneous vector is assumed (0,0,0,1) in the target system. Any thoughts on converting properly?
Advertisement
hey

Firstly I think you need to identify how the matrices are structure in your program? are you using OpenGL? if so then your matrices would most likely be 16 element arrays, and when written out in order would form a column major matrix. edit, nevermind I see you already mentioned how they are structured and such, hehe.

Usually OpenGL documentation displays matrices in column major, but the matrix you have presented here is row major, so I dunno.

That said, the difference between right handled and left handed coordinate systems is that for Right Handed the Z axis comes towards us, and for Left Handed the Z axis goes away from us.

So to switch from Right Handed to Left Handed then I think you need to invert the Z value of each of your vectors.

So I think your matrix would become...

1, Inverted the Z value of each vector.
-0.0312836 -0.00783613 0.013012 0 (X-Axis Basis)
-0.012188 0.0731294 0.0147378 0 (Y-Axis Basis)
-0.0297495 0.00843272 -0.0664458 0 (Z-Axis Basis)
0.104637 0.507761 0.0222363 1 (translation: x,y,z)

BTW, the transpose of the inner 3x3 matrix equals the inverse of an orthogonal matrix. BUT, this is not useful as you don't want to invert your X and Y axis ;). So I thinks anyhows.

another edit
Hmm, because you haven't mentioned anything about what gave you the idea that you need to change from a right to left handed coordinate system, then it makes me think... are you sure changing from left to right handed is the solution? I have no idea, as I know nothing about the situation. But I thought this might be worth mentioning.

Ohh, and when you say...

Quote:This is for a coordinate system transformation not points, projection, so on.

Are you saying your points were defined in/for a left handed coordinate system?

cya

[Edited by - yosh64 on January 19, 2008 8:31:36 PM]
The source application uses a right-handed coordinate system.

The target application uses a left-handed coordinate system.

The information stored in the file from the source application is a matrix which is obviously stored in right-handed form (for the source application) but, as you note, looks to be row-major instead of column-major. Go figure any standardization, huh?

No OpenGL or DirectX involved.

The matrix (there is more than one but the example is one that definitely isn't being converted properly) is a global transformation matrix applied to a unit sphere (at the world origin, scales 1, rotations 0d). So, I'm trying to convert the matrices to be used by the target application. Since it employs a left-handed coordinate system, it is necessary to convert the matrix.

Again, scales work independent of these two systems (the scales will always be positive from the source system), translations just require negation of the z-axis value. But rotations are a bugger, especially since matrices don't store them independently. One cannot just negate the 'z rotation' as it is spread about and mixed with the other rotations. I'm starting to think that there really isn't a proper way to accomplish this for any generic transformation matrix using a similarity matrix (or there'd be a solid answer that always works instead of a bunch of gibbering about this, that, or the other method).

Now, I could go the longer route and do a matrix decomposition to extract the Euler rotations (after removing the translations and scales from it). Then the z rotation could be negated and a new matrix built. I've also tried this with limited success. The problem here is that matrix to Euler rotations methods tend to zero the z rotation which, eh hem, negates the effect of negation (+0 = -0). It would then need to be passed to another rotation. Which or both?

I'll let the ivory towers shake and see if there is a mathematical-minded person who can answer this definitely.

This person seems to be explaining these same problematics in this thread, but I've come to think that the matrix here and the ones with which I'm dealing are not the same (or the results being sought are not the same):

Link to another forum

ETA: A bit more information to digest. Studying the rotations of a sphere (at world origin) in both applications shows these properties for positive angles looking down each positive axis towards the origin:

App 1 (RH): X=CCW, Y=CCW, Z=CCW
App 2 (LH): X=CCW, Y=CCW, Z=CCW

I can't remember the directions these rotations usually occur for each handed system offhand (heh) but could this be part of the problem? I'll see about finding the usual clockwise (CW) or counter-clockwise (CCW) directions for rotations for right and left handed systems.

ETA2: Okay, well, this site shows a left-handed system being all rotations clockwise:

www.3dmath.net

I'm not only positive that the target application is left-handed, I'm absolutely - you can cut off one of my body parts if I'm wrong - positive (it's directly mentioned in the app's SDK and obvious looking at the view window in the app). So, although the handedness of the systems is opposite, the direction of rotations is the same between them (though the z rotations are opposite due to the fact that RH z points one direction and LH z points the other).

Thoughts? Any thoughts?

Thanks!

[Edited by - Kuroyume0161 on January 19, 2008 9:44:53 PM]
hey

Well I think not only would you need to convert the matrices and such used in the source of whatever ya porting, but you also all the points, normals and other such data, as these would have been produced in/for a right handed coordinate system. Anyhows, again I think you would just need to invert the Z value of all your points and matrices and such?

Hmm, I think I remember having a simular issue when converting the tony hawks pro skater models for opengl. Speaking of which, I think I might have had todo the same when making a converter for the directx *.x format, but not exactly sure.

Anyhows, I just remembered something with the directx exporter for blender, it actually has the option "Flip z" and when pressed the caption next to it reads "left handed system", otherwise "right handed system". So I might export a small model and animation and see how the vertices/matrices differ.

Something else I thought I might make note of, is there is also an option to swap the z and y axis. Hmm, maybe this was the issue I was having, but I can't really remember.

Anyhows I'll go export some things now and compare the data, and post my findings. Hopefully it will be of some help.

edit
I just done a really quick comparison, and interesting enough everything stayed the same except, the Z value of the Z axis was inverted for the left handed root transformation matrix (which happened to be an identity matrix, so I'm not sure if any other values were inverted or whatever). Anyhows I think this actually makes sense :).

Anyhows I think I might have a solution for you ^_^.

That is before you do anything on a frame, instead of setting the modelview matrix to the usual identity matrix, set it with the Z axis inverted :).

As such...
1, 0, 0, 0
0, 1, 0, 0
0, 0, -1, 0
0, 0, 0, 1

Hmm, this is assuming that it's somewhat alike opengl with some sorta modelview matrix, anyhows hopefully you can do something simular. Otherwise if there is a function to get an identity matrix, then maybe you could modify this instead? but I'm not completly sure on this.

Anyhows I hope this is of some help :).

cya

[Edited by - yosh64 on January 20, 2008 12:10:56 AM]
I multiplied the input matrix with the identity matrix (with the one value negated as shown) trying both pre- and post-multiplication. Not doing it. This is pretty much the last-try idea that I had - apply a matrix with a negative z-scale to flip the axes. I might try a negative x-scale to see the results - but am not holding breath.

All of these methods work here and there - but don't work on every case. So there is definitely something missing in the equation. Transposing the input matrix and applying a similarity matrix covered more cases - but still not all. And I think that this is because it flips all of the rotations. This won't work here. The only rotation needing flipping is the z-axis rotation.

Unfortunately, there is no possibility of rectifying these matrices before input into the target application.

Thanks for you input so far, yosh64!

As can be seen by the stampede of assistance otherwise, nope, no brave mathematicians around (yes, I'm prodding). If I said "OpenGL to DirectX" there'd be fifty links and definite methods. Sorry, this isn't what I'm working with. The source application has its ways (which cannot be changed) and the target application has its ways - and its SDK doesn't consider things like right-to-left handed matrix conversion. Definitely not as deep and wide of breadth as these more generic graphics interfaces.
Solved! :)

First, the rotation order is indeed YXZ (yes!). Second, the input matrix is in right-handed, row-major format (see "3D Computer Graphics" by Alan Watts (pp. 4 & 5)). Most other sources use a column-major format so the rotation extraction routines (Eberly) needed to consider the transposition of matrix elements. Third, instead of negating the z rotation, obviously :sarcasm: you have to negate the x and y rotations. Finally, the matrix determinant is then needed to negate these in the opposite direction (a positive determinant, multiply by -1, a negative determinant, multiply by 1).

I'm going to take a nap now! ;)

See. Sometimes a similarity matrix or simple reflection matrix will NOT suffice to convert a matrix in one handed system to the other. The similarity matrix may suffice if the determinant is also applied (hmm) but the matrix decomposition with the fiddly bits allows confirmable value comparisons and more direct control of the conversion.

You guys need to get your heads out of OpenGL and DirectX more often. There is a world of maddeningly subtle pain that awaits you.

This topic is closed to new replies.

Advertisement