Changing a matrix from right-handed to left-handed

2020-01-25 05:29发布

I would like to change a 4x4 matrix from a right handed system where:
x is left and right, y is front and back and z is up and down

to a left-handed system where:
x is left and right, z is front and back and y is up and down.

For a vector it's easy, just swap the y and z values, but how do you do it for a matrix?

标签: math graphics
7条回答
神经病院院长
2楼-- · 2020-01-25 05:58

Let me try to explain it a little better. I need to export a model from Blender, in which the z axis faces up, into OpenGL, where the y axis faces up.

For every coordinate (x, y, z) it's simple; just swap the y and z values: (x, z, y).
Because I have swapped the all the y and z values, any matrix that I use also needs to be flipped so that it has the same effect.

After a lot of searching I've eventually found a solution at gamedev:

If your matrix looks like this:

{ rx, ry, rz, 0 }  
{ ux, uy, uz, 0 }  
{ lx, ly, lz, 0 }  
{ px, py, pz, 1 }

To change it from left to right or right to left, flip it like this:

{ rx, rz, ry, 0 }  
{ lx, lz, ly, 0 }  
{ ux, uz, uy, 0 }  
{ px, pz, py, 1 }
查看更多
在下西门庆
3楼-- · 2020-01-25 05:58

Change sin factor to -sin for swaping coordinate spaces between right and left handed

查看更多
可以哭但决不认输i
4楼-- · 2020-01-25 06:01

I think I understand your problem because I am currently facing a similar one.

  • You start with a world matrix which transforms a vector in a space where Z is up (e.g. a world matrix).

  • Now you have a space where Y is up and you want to know what to do with your old matrix.

Try this:

There is a given world matrix

Matrix world = ...  //space where Z is up

This Matrix changes the Y and Z components of a Vector

Matrix mToggle_YZ = new Matrix(
{1, 0, 0, 0}
{0, 0, 1, 0}
{0, 1, 0, 0}
{0, 0, 0, 1})

You are searching for this:

//same world transformation in a space where Y is up
Matrix world2 = mToggle_YZ * world * mToggle_YZ;

The result is the same matrix cmann posted below. But I think this is more understandable as it combines the following calculation:

1) Switch Y and Z

2) Do the old transformation

3) Switch back Z and Y

查看更多
ゆ 、 Hurt°
5楼-- · 2020-01-25 06:04

Since this seems like a homework answer; i'll give you a start at a hint: What can you do to make the determinant of the matrix negative?

Further (better hint): Since you already know how to do that transformation with individual vectors, don't you think you'd be able to do it with the basis vectors that span the transformation the matrix represents? (Remember that a matrix can be viewed as a linear transormation performed on a tuple of unit vectors)

查看更多
Rolldiameter
6楼-- · 2020-01-25 06:18

It is often the case that you want to change a matrix from one set of forward/right/up conventions to another set of forward/right/up conventions. For example, ROS uses z-up, and Unreal uses y-up. The process works whether or not you need to do a handedness-flip.

Note that the phrase "switch from right-handed to left-handed" is ambiguous. There are many left-handed forward/right/up conventions. For example: forward=z, right=x, up=y; and forward=x, right=y, up=z. You should really think of it as "how do I convert ROS' notion of forward/right/up to Unreal's notion of forward/right/up".

So, it's a straightforward job to create a matrix that converts between conventions. Let's assume we've done that and we now have

mat4x4 unrealFromRos = /* construct this by hand */;
mat4x4 rosFromUnreal = unrealFromRos.inverse();

Let's say the OP has a matrix that comes from ROS, and she wants to use it in Unreal. Her original matrix takes a ROS-style vector, does some stuff to it, and emits a ROS-style vector. She needs a matrix that takes an Unreal-style vector, does the same stuff, and emits an Unreal-style vector. That looks like this:

mat4x4 turnLeft10Degrees_ROS = ...;
mat4x4 turnLeft10Degrees_Unreal = unrealFromRos * turnLeft10Degrees_ROS * rosFromUnreal;

It should be pretty clear why this works. You take a Unreal vector, convert it to ROS-style, and now you can use the ROS-style matrix on it. That gives you a ROS vector, which you convert back to Unreal style.

Gerrit's answer is not quite fully general, because in the general case, rosFromUnreal != unrealFromRos. It's true if you're just inverting a single axis, but not true if you're doing something like converting X->Y, Y->Z, Z->X. I've found that it's less error-prone to always use a matrix and its inverse to do these convention switches, rather than to try to write special functions that flip just the right members.

This kind of matrix operation inverse(M) * X * M comes up a lot. You can think of it as a "change of basis" operation; to learn more about it, see https://en.wikipedia.org/wiki/Matrix_similarity.

查看更多
叛逆
7楼-- · 2020-01-25 06:20

It depends if you transform your points by multiplying the matrix from the left or from the right.

If you multiply from the left (e.g: Ax = x', where A is a matrix and x' the transformed point), you just need to swap the second and third column. If you multiply from the right (e.g: xA = x'), you need to swap the second and third row.

If your points are column vectors then you're in the first scenario.

查看更多
登录 后发表回答