python中4x3矩阵的逆

python中4x3矩阵的逆,python,math,matrix,inverse,Python,Math,Matrix,Inverse,我正在重新实现一个名为noesis的封闭源代码3d库 它公开了一个包含所有基本类的python文件 所有的实现细节实际上都是隐藏的。该实现已编译,因此我无法预览它 我想实现这个名为MAT43Reverse的库中的一个功能 我知道通常不可能求4x3矩阵的逆,但这个函数是存在的 noesis插件的示例用法: #4x3 matrix class NoeMat43: # ... def inverse(self): #returns mat43 return noes

我正在重新实现一个名为noesis的封闭源代码3d库

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


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

我想实现这个名为MAT43Reverse的库中的一个功能

我知道通常不可能求4x3矩阵的逆,但这个函数是存在的

noesis插件的示例用法:

#4x3 matrix
class NoeMat43:

    # ...

    def inverse(self): #returns mat43
        return noesis.mat43Inverse(self)
公开类文件的源:

noesis模块是一个编译的cpython模块。()

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

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)
正确的结果

一,

二,

三,

四,

五,

问题:

  • 逆函数背后的公式是什么

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

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

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

  • 霍纳方案/GEM高斯消去法

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

  • 从行列式求逆

    这是未知矩阵的最佳选择,因为它不需要排序,并且如果矩阵有逆矩阵,它总是可计算的。如果使用的数字/矢量的大小过大,有时会出现精度问题。这里C++中的代码(OpenGL约定):

    在代码中查找
    matrix\u inv
    函数

  • 伪逆矩阵

    在某些情况下,您可以避免使用行列式或霍纳方案/高斯消去法计算逆矩阵,因为在某些情况下,您可以利用
    正交旋转矩阵的
    转置
    也是其
    这一事实。因此,计算归结为3x3矩阵的简单变换(仅交换元素)和计算线性方程以匹配逆矩阵原点。这大大减少了计算量,因此具有更好的精度和速度。下面是如何完成的(OpenGL约定):

    在那里寻找子弹3


  • 不知道,但是你不能找到函数的存储位置并打开相应的文件吗?它在python模块中?所有的实现细节实际上都是隐藏的。这个实现是编译的,所以我不能预览它。我建议在所有简单的矩阵上尝试该函数,如截断单位矩阵、单位矩阵乘以常数等。至少你会了解该函数的线性度。另外,文档说明了什么以及该函数通常在何处/如何使用?由于这是一个3d库,很可能最后一列被隐藏,并假定为
    (0,0,0,1)
    。您的一些示例支持此假设,但并非所有示例都支持此假设。您确定这些值正确吗?
    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)
    
    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)
    )
    
    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)
    )
    
    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)
    )
    
    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)
    )
    
    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)
    )