如何检测视图矩阵是左手矩阵还是右手矩阵?

问题描述 投票:0回答:3

我有一个从 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 相对容易 - 我使用这些信息来识别坐标系。

opengl graphics matrix
3个回答
4
投票

你应该求矩阵的行列式。 在其他条件相同的情况下,左手矩阵和右手矩阵应该具有符号相反的行列式。

这有点奇怪,因为“左撇子”和“右手”几乎是任意的约定。 但是,像镜子一样反映世界的矩阵具有负行列式,因此乘以这样的矩阵将改变行列式的符号。


编辑(参考更新的 OQ):我怀疑

D3DX*LH()
D3DX*RH()
函数之间的区别在于它们支持 2 种不同的约定。

如果是这样,您应该意识到“左手”和“右手”不是每个单独矩阵的属性,而是这些函数集生成的矩阵如何组合在一起的属性。 如果您坚持使用

*LH()
功能,一切都会正常进行;与
*RH()
函数类似 - 但如果将它们混合使用,您可能会得到意想不到的结果。

无论如何,这些约定都与 GL 无关,GL 有自己的一套约定,与 D3D 的任何一个都不完全兼容。 例如,GL 的 Z 裁剪约定与 D3D 的不同;这意味着生成相同视图的投影矩阵在系统之间必然有所不同。

所以,对你的问题的简短回答是“可能两者都不是”。


2
投票

刚刚绑定了相同的任务(仅用于检测镜像变换的对象),找到了一个简单的解决方案,分享它。如果矩阵有一个包含 3 个垂直轴的 3x3 部分,那么您只需对轴 1 和轴 2 进行叉积,然后对该结果与剩余的第 3 个轴进行标量积。检查它是负数还是正数 - 您可以决定右手/左手/物体是否镜像。如果我正确理解了这个问题...


0
投票

不幸的是,视图矩阵本身不携带有关坐标系惯用手的信息。 (正确构造的)视图矩阵始终满足轴关系的顺序:

z = cross(x, y)
x = cross(y, z)
y = cross(z, x)

此顺序适用于左手和右手坐标系以及各自的视图矩阵。这就是为什么基于行列式或交叉和点/标量积串联的方法在这里没有帮助(两者最终都是同一件事)。视图矩阵始终表示方向,但不表示依赖于惯用手的镜像或类似的东西。

但幸运的是你仍然有投影矩阵,你已经用它来解决你的问题了。确实,您可以检查

matrix[3][4]
,但仅限于透视投影矩阵。为了完整起见,我想指出,对于正交投影矩阵也有效的一般方法可能是检查
matrix[3][3]
以查看它是否包含正(左手)或负(右) - 手)值。这就是圆闭合的地方,因为与左手坐标系相比,右手坐标系具有镜像 Z 轴。

© www.soinside.com 2019 - 2024. All rights reserved.