如何检测视图矩阵是左手矩阵还是右手矩阵?
我有一个从 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 相对容易 - 我使用这些信息来识别坐标系。
I have a camera view matrix which I received from a GL program. I know that this matrix is right-handed since this is the way GL works, but how can I check whether this matrix is right-handed or left-handed programmatically?
For the projection matrix I check if matrix[3][4] (row major) is positive to see if it's left handed. Is this correct?
Thanks.
EDIT:
I have tried the determinant solution, but unfortunately it is not true (at least according to my experiments):
I have used DX9 math functions to test it (to avoid any possible bugs in my code).
I have run the following code:
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);
And the two determinants were equal (both equal to 0.99999994), and obviously had the same sign.
As for my problem - Since I get both the view matrix and projection matrix, and it's relatively easy for me to test whether the projection matrix is LH or RH - I use this information to identify the coordinate system.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您应该计算矩阵的行列式。在其他条件相同的情况下,左手矩阵和右手矩阵应该具有符号相反的行列式。
这有点奇怪,因为“左撇子”和“右手”几乎是任意的约定。但是,像镜子一样反映世界的矩阵具有负行列式,因此乘以这样的矩阵将改变行列式的符号。
编辑(参考更新的 OQ):我怀疑
D3DX*LH()
和D3DX*RH()
函数之间的区别在于它们支持 2 种不同的约定。如果是这样,您应该意识到“左手”和“右手”不是每个单独矩阵的属性,而是这些函数集生成的矩阵如何组合在一起的属性。如果您坚持使用
*LH()
函数,一切都应该正常进行;与*RH()
函数类似 - 但如果将它们混合使用,您可能会得到意想不到的结果。无论如何,这些约定都与 GL 无关,GL 有自己的一套约定,与 D3D 中的任何一个都不完全兼容。例如,GL 的 Z 裁剪约定与 D3D 的不同;这意味着生成相同视图的投影矩阵在系统之间必然有所不同。
因此,对你的问题的简短回答是“可能两者都不是”。
You should take the determinant of the matrix. Other things being equal, left-handed and right-handed matrices should have determinants with opposite signs.
It's a little weird because "left-handed" and "right-handed" are pretty much arbitrary conventions. But, matrices that reflect the world like a mirror have negative determinants, so multiplying by such a matrix will change the sign of the determinant.
Edit (ref. updated OQ): I suspect the difference between the
D3DX*LH()
andD3DX*RH()
functions is that they support 2 different conventions.If so, you should be aware that "left-handed" and "right-handed" is not an attribute of each individual matrix, but of how the matrices generated by these sets of functions fit together. If you stick with the
*LH()
functions, everything should work out properly; similarly with the*RH()
functions -- but if you mix them, you will likely get unexpected results.In any case, neither of these conventions is relevant to GL, which has its own set of conventions, not fully compatible with either of D3D's. For example, GL's convention for Z clipping is different from D3D's; this means that the projection matrix to generate the same view will necessarily differ between the systems.
So, the short answer to your question is "probably neither".
只是绑定了相同的任务(仅用于检测镜像变换的对象),找到了一个简单的解决方案,分享它。如果矩阵有一个包含 3 个垂直轴的 3x3 部分,那么您只需对轴 1 和轴 2 进行叉积即可。 2,然后计算该结果与剩余第三轴的标量积。检查它是负数还是正数 - 您可以决定右手/左手/物体是否镜像。如果我正确理解了这个问题...
Just bound this same task (just for detecting mirror-transformed objects), found an easy solution, sharing it. If the matrix has a 3x3 part containing 3 perpendicular axes, then you can just make a cross product of axes 1 & 2, then do a scalar product of this result and the remaining 3rd axle. Check if it's negative or positive - you can decide about right/left handedness / object mirrored or not. If I understood the question right...
不幸的是,视图矩阵本身不携带有关坐标系的惯用手的信息。 (正确构造的)视图矩阵始终满足轴关系的顺序:
此顺序适用于左手和右手坐标系以及各自的视图矩阵。这就是为什么基于行列式或叉积和点/标量积串联的方法在这里没有帮助(两者最终都是同一件事)。视图矩阵始终表示方向,但不表示依赖于惯用手的镜像或类似的东西。
但幸运的是,您仍然拥有投影矩阵,您已经使用它来解决您的问题。确实,您可以检查
matrix[3][4]
,但仅限于透视投影矩阵。为了完整起见,我想指出,对于正交投影矩阵也有效的一般方法可能是检查matrix[3][3]
以查看它是否包含正(左手)或负(右手)值。这就是圆闭合的地方,因为与左手坐标系相比,右手坐标系具有镜像 Z 轴。Unfortunately, a view matrix itself doesn't carry information about the handedness of the coordinate system. A (correctly constructed) view matrix always fulfills the order of the axis relationships:
This order applies to both left- and right-handed coordinate systems and respective view matrices. And that is why approaches based on the determinant or a concatenation of cross and dot/scalar products are of no help here (both ultimately amount to the same thing). The view matrix always represents an orientation, but not a handedness-dependent mirroring or anything like that.
But luckily you still have the projection matrix, which you have already used for solving your problem. And it is true that you can check
matrix[3][4]
, but only for perspective projection matrices. For the sake of completeness, I would like to note that the general approach, which would also be valid for orthogonal projection matrices, would probably be to checkmatrix[3][3]
to see whether it contains a positive (left-handed) or negative (right-handed) value. And this is where the circle closes, because a right-handed coordinate system has a mirrored Z-axis compared to a left-handed one.