反转python中的4x3矩阵

时间:2018-01-04 21:54:41

标签: python math matrix inverse

我重新实现了一个名为noesis的封闭源3d库。

它公开了一个包含所有基本类的python文件。

所有实施细节实际上都是隐藏的。编译实现,因此我无法预览它。

我想从该库中实现一个名为mat43Inverse的函数。

我通常知道它不可能反转4x3矩阵,但是这个函数存在。

来自noesis插件的示例用法:

#4x3 matrix
class NoeMat43:

    # ...

    def inverse(self): #returns mat43
        return noesis.mat43Inverse(self)

公开的类文件的来源:https://github.com/majimboo/mviewer/blob/master/noesis/plugins/python/inc_noesis.py#L478

noesis模块是一个已编译的cpython模块。 (https://github.com/majimboo/mviewer/blob/master/noesis/plugins/NoesisPython.dll

boneMtx = NoeMat43((
  NoeVec3((m01, m02, m03)),
  NoeVec3((m11, m12, m13)),
  NoeVec3((m21, m22, m23)),
  NoeVec3((m04, m14, m24))
)).inverse()

我通过调用本机函数并打印结果来准备一组正确的结果。

input = NoeMat43((
    NoeVec3((2.5, 3.6, 4.7)),
    NoeVec3((2.9, 3.1, 4.3)),
    NoeVec3((6.5, 7.6, 8.7)),
    NoeVec3((1.1, 9.4, 3.2))
))

result = input.inverse()
expected = NoeMat43((
    NoeVec3((0.04392901062965393, 0.05095765367150307, 0.1142154261469841)),
    NoeVec3((0.044815145432949066, 0.038590818643569946, 0.09460975229740143)),
    NoeVec3((0.04042314738035202, 0.036982882767915726, 0.07482582330703735)),
    NoeVec3((-0.8928132057189941, -0.714801549911499, -0.6315471529960632))
))
noeassert('mat43Inverse', result, expected)

结果正确

1

input: (
(1, 0, 0),
(0, 1, 0),
(0, 0, 1),
(0, 0, 0)
)

inverse result: (
(1.0, 0.0, 0.0),
(0.0, 1.0, 0.0),
(0.0, 0.0, 1.0),
(0.0, 0.0, 0.0)
)

2

input: (
(2.5, 3.6, 4.7),
(2.9, 3.1, 4.3),
(6.5, 7.6, 8.7),
(1.1, 9.4, 3.2)
)

invserse result: (
(0.04392901062965393, 0.05095765367150307, 0.1142154261469841),
(0.044815145432949066, 0.038590818643569946, 0.09460975229740143),
(0.04042314738035202, 0.036982882767915726, 0.07482582330703735),
(-0.8928132057189941, -0.714801549911499, -0.6315471529960632)
)

3

input: (
(0.0, 0.0, 1.0),
(0.0, 1.0, 0.0),
(-1.0, 0.0, 0.0),
(0.0, 32.29199981689453, -3.2665998935699463)
)

inverse result: (
(0.0, 0.0, -1.0),
(0.0, 1.0, 0.0),
(1.0, 0.0, 0.0),
(-3.2665998935699463, -32.29199981689453, 0.0)
)

4

input: (
(0.0, 0.0, 2.0),
(0.0, 2.0, 0.0),
(-2.0, 0.0, 0.0),
(0.0, 32.29199981689453, -3.2665998935699463)
)

inverse result: (
(0.0, 0.0, -0.5),
(0.0, 0.5, 0.0),
(0.5, 0.0, 0.0),
(-1.6332999467849731, -16.145999908447266, 0.0)
)

5

input: (
(2.0, 0.0, 2.0),
(0.0, 2.0, 0.0),
(-2.0, 0.0, 0.0),
(0.0, 32.29199981689453, -3.2665998935699463)
)

inverse result: (
(0.2499999850988388, 0.0, -0.2499999850988388),
(0.0, 0.5, 0.0),
(0.5, 0.0, 0.0),
(-0.8166499137878418, -16.145999908447266, 0.0)
)

问题:

  • mat43Inverse函数背后的公式是什么?

1 个答案:

答案 0 :(得分:2)

Nico Schertler 指出 3D 图形中的 4x3 矩阵通常是 4x4 均匀变换矩阵,其中最后一个行或列(取决于使用的约定)被省略并表示(0,0,0,1)向量(无投影)。这通常是为了保留空间。

我懒得检查你的样品,但如果结果不匹配,你很可能对矩阵的元素/细胞的排序方式有不同的约定。要检查正确性,只需将原始矩阵和逆矩阵相乘(均为完整的4x4表示),结果应为单位矩阵。

我知道有三种方法可以计算 3D 图形中的逆矩阵:

  1. 霍纳方案/ GEM高斯消除方法

    这是一种在纸上可以使用的直接方法,但在计算机计算中这不是一个很好的选择,因为它需要有点复杂来排序行,所以结果仍然导致反向。这有时会导致反复试验,这意味着后来可能出现性能问题。

  2. 来自行列式的反转

    这是未知矩阵的最佳选择,因为它不需要排序,并且如果矩阵具有逆矩阵,则总是可计算的。如果使用的数字/矢量具有太大的幅度,则有时存在准确性问题。这里用C ++编写代码(OpenGL约定):

    在代码中查找matrix_inv函数。

  3. 伪逆矩阵

    在某些情况下,您可以避免通过决定因素或Horner方案/高斯消除法计算逆矩阵,因为在某些情况下,您可以利用正交旋转矩阵Transpose的事实它的inverse。因此,计算归结为简单的3x3矩阵转换(仅交换元素)和计算线性方程以匹配逆矩阵原点。这是更少的计算,因此更好的准确性和速度。以下是它的完成方式(OpenGL约定):

    在那里寻找子弹#3