0

你如何反转只有平移和旋转,没有比例的 4x3 矩阵?你会用什么来做一个OpenGL矩阵逆(只是没有缩放)?

4

2 回答 2

1

假设您的 TypeMatrix3x4 是一个 [3][4] 矩阵,并且您只是转换一个 1:1 的比例、旋转和平移矩阵,下面的代码似乎可以工作 -

这会转置旋转矩阵并应用平移的逆矩阵。

TypeMatrix3x4 InvertHmdMatrix34( TypeMatrix3x4 mtoinv )
{
    int i, j;
    TypeMatrix3x4 out = { 0 };
    for( i = 0; i < 3; i++ )
        for( j = 0; j < 3; j++ )
            out.m[j][i] = mtoinv.m[i][j];

    for ( i = 0; i < 3; i++ )
    {
        out.m[i][3] = 0;
        for( j = 0; j < 3; j++ )
            out.m[i][3] += out.m[i][j] * -mtoinv.m[j][3];
    }
    return out;
}
于 2021-09-29T12:08:02.677 回答
0

You can solve that for any 3 dimensional affine transformation whose 3x3 transformation matrix is invertible. This allows you to include scaling and non conformant applications. The only requirement is for the 3x3 matrix to be invertible.

Simply extend your 3x4 matrix to 4x4 by adding a row all zeros except the last element, and invert that matrix. For example, as shown below:

[[a  b   c   d]  [[x]    [[x']
 [e  f   g   h] * [y]  =  [y']
 [i  j   k   l]   [z]     [z']
 [0  0   0   1]]  [1]]    [1 ]]  (added row)

It's easy to see that this 4x4 matrix, applied to your vector produces exactly the same vector as before the extension.

If you get the inverse of that matrix, you'll have:

[[A  B   C   D]    [[x']    [[x]
 [E  F   G   H]  *  [y']  =  [y]
 [I  J   K   L]     [z']     [z]
 [0  0   0   1]]    [1 ]     [1]]

It's easy to see that it this works in one direction, it needs to be in the reverse direction, if A is the image of B, then B will be the inverse throug the inverse transformation, the only requisite is the matrix to be invertible.

More on... if you have a list of vectors you want to process, you can apply Gauss elimination method to an extended matrix of the form:

[[a  b   c   d     x0' x1' x2' ... xn']
 [e  f   g   h     y0' y1' y2' ... yn']
 [i  j   k   l     z0' z1' z2' ... zn']
 [0  0   0   1     1   1   1   ... 1  ]]

to obtain the inverses of all the vectors you do the Gauss elimination vector to get from above:

[[1  0   0   0     x0  x1  x2  ... xn ]
 [0  1   0   0     y0  y1  y2  ... yn ]
 [0  0   1   0     z0  z1  z2  ... zn ]
 [0  0   0   1     1   1   1   ... 1  ]]

and you will solve n problems in one shot, because the column vectors above will be the ones, that once transformed produce the former ones.

You can get a simple implementation I wrote to teach my son about linear algebra of Gauss/Jordan elimination method here. It's opensource (BSD license) and you can modify/adapt it to your needs. This method uses the last approach, and you can use it out of the box by trying the sist_lin program.

If you want the inverse transformation, put the following contents in the matrix, and apply Gauss elimination to:

a b c d 1 0 0 0
e f g h 0 1 0 0
i j k l 0 0 1 0
0 0 0 1 0 0 0 1

as input to sist_lin and you get:

1 0 0 0 A B C D   <-- these are the coefs of the
0 1 0 0 E F G H       inverse transformation
0 0 1 0 I J K L
0 0 0 1 0 0 0 1

you will have:

a * x + b * y + c * z + d = X
e * x + f * y + g * z + h = Y
i * x + j * y + k * z + l = Z
0 * x + 0 * y + 0 * z + 1 = 1

and

A * X + B * Y + C * Z + D = x
E * X + F * Y + G * Z + H = y
I * X + J * Y + K * Z + L = z
0 * X + 0 * Y + 0 * Z + 1 = 1
于 2021-10-04T17:08:47.783 回答