如何检测一个视图矩阵是左手坐标系还是右手坐标系?

6
我有一个相机视图矩阵,是从GL程序中获取的。我知道这个矩阵是右手坐标系,因为这是GL工作的方式,但我该如何以编程方式检查这个矩阵是右手坐标系还是左手坐标系?
对于投影矩阵,我检查矩阵[3][4](行主序)是否为正数,以查看它是否是左手坐标系。这正确吗?
谢谢。
编辑:
我尝试了行列式解法,但不幸的是它并不正确(至少根据我的实验结果是这样的):
我使用DX9数学函数进行测试(以避免我的代码中可能存在的任何错误)。我运行了以下代码:
 D3DXVECTOR3 vEye(0,0,0);
 D3DXVECTOR3 vTarget(6,3,0);
 D3DXVECTOR3 vUp(0,0,1);

 D3DXMATRIX matViewLH;
 D3DXMATRIX matViewRH;

 D3DXMatrixLookAtLH(&matViewLH, &vEye, &vTarget, &vUp);
 D3DXMatrixLookAtRH(&matViewRH, &vEye, &vTarget, &vUp);

 float fLHDet = D3DXMatrixDeterminant(&matViewLH);
 float fRHDet = D3DXMatrixDeterminant(&matViewRH);

两个决定因素相等(均为0.99999994),显然具有相同的符号。

至于我的问题-由于我得到了视图矩阵和投影矩阵,而且很容易测试投影矩阵是LH还是RH-我使用这些信息来确定坐标系。

2个回答

4
您应该计算矩阵的行列式。其他条件相同,左手和右手矩阵的行列式应该具有相反的符号。
这有点奇怪,因为“左手”和“右手”几乎是任意惯例。但是,像镜子一样反射世界的矩阵具有负行列式,因此乘以这样的矩阵将改变行列式的符号。
编辑(参考更新OQ):我怀疑D3DX*LH()D3DX*RH()函数之间的区别在于它们支持2种不同的约定。
如果是这样,请注意,“左手”和“右手”不是每个单独矩阵的属性,而是由这些函数生成的矩阵如何拟合在一起的属性。如果您坚持使用*LH()函数,一切都应该正常工作;同样适用于*RH()函数-但是如果您混合使用它们,则可能会得到意外的结果。
在任何情况下,这两种约定都与GL无关,GL具有自己的约定,与D3D的约定不完全兼容。例如,GL的Z剪辑约定与D3D的不同;这意味着生成相同视图的投影矩阵在系统之间必然不同。
因此,对您的问题的简短回答是“可能都不是”。

并不是完全随意的。如果正X在右边,正Y在上方 - 那么左手坐标系意味着正Z向前 - 远离观察者,而右手坐标系意味着正Z朝向观察者。我不确定您的答案是否解决了我的问题:我不是要比较具有相同参数的两个矩阵,而是要确定特定视图矩阵的正Z方向。 - Asaf
2
创建一个已知的右手矩阵,并将其行列式与你的矩阵进行比较。如果它们不同,那么你有一个左手矩阵。否则它就是右手矩阵。 - Ron Warholic
@Asaf,你是正确的。然而,我的观点是,左右惯性与GL系统无关。GL不知道任何关于左右惯性的事情;它是用户为他的应用程序选择的任何约定的结果。 - comingstorm
1
-1 - 感谢您的回答,但不幸的是我已经测试过了,似乎并不正确(请参考我的问题帖子了解详情)。 - Asaf
1
嗯,我查看了D3DX参考文献,不清楚他们所说的“左手坐标系”到底是什么意思。MatrixLookAtLH()MatrixLookAtRH()矩阵之间的区别应该是绕结果y轴旋转180度--矩阵本身应该始终具有(正如您发现的)行列式为1。也许问题在于您试图将D3DX约定应用于GL系统,而这并不适用? - comingstorm
1
D3DXMatrixLookAtLH 使用从__eye__到__at__的实际前向量,而D3DXMatrixLookAtRH使用“反向”的前向量(从__at__到__eye__)。 - bobobobo

1

我刚刚绑定了同样的任务(仅用于检测镜像转换的对象),找到了一个简单的解决方案,现在分享给大家。如果矩阵中有一个包含3个垂直轴的3x3部分,则可以将轴1和2进行叉积,然后将此结果与剩余的第3个轴进行标量积。检查它是负数还是正数 - 您可以决定右手/左手性/对象是否为镜像。如果我正确理解了问题...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接