我重新实现了一个名为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)
)
问题:
答案 0 :(得分:2)
Nico Schertler 指出 3D 图形中的 4x3 矩阵通常是 4x4 均匀变换矩阵,其中最后一个行或列(取决于使用的约定)被省略并表示(0,0,0,1)
向量(无投影)。这通常是为了保留空间。
我懒得检查你的样品,但如果结果不匹配,你很可能对矩阵的元素/细胞的排序方式有不同的约定。要检查正确性,只需将原始矩阵和逆矩阵相乘(均为完整的4x4表示),结果应为单位矩阵。
我知道有三种方法可以计算 3D 图形中的逆矩阵:
霍纳方案/ GEM高斯消除方法
这是一种在纸上可以使用的直接方法,但在计算机计算中这不是一个很好的选择,因为它需要有点复杂来排序行,所以结果仍然导致反向。这有时会导致反复试验,这意味着后来可能出现性能问题。
来自行列式的反转
这是未知矩阵的最佳选择,因为它不需要排序,并且如果矩阵具有逆矩阵,则总是可计算的。如果使用的数字/矢量具有太大的幅度,则有时存在准确性问题。这里用C ++编写代码(OpenGL约定):
在代码中查找matrix_inv
函数。
伪逆矩阵
在某些情况下,您可以避免通过决定因素或Horner方案/高斯消除法计算逆矩阵,因为在某些情况下,您可以利用正交旋转矩阵的Transpose
的事实它的inverse
。因此,计算归结为简单的3x3矩阵转换(仅交换元素)和计算线性方程以匹配逆矩阵原点。这是更少的计算,因此更好的准确性和速度。以下是它的完成方式(OpenGL约定):
在那里寻找子弹#3 。