来自法向量的旋转矩阵,绕极点翘曲

时间:2013-11-01 01:05:11

标签: c# math vector matrix xna

我有一台需要围绕物体绕地球运行的摄像机。该对象具有任意旋转,由法向量描述。想象一个球形行星,用相机俯视那个星球上的某个三角形。

我目前的实现是使用经典的矢量交叉方法从三角形的法线生成旋转矩阵,然后使用该矩阵作为标准轨道相机的基础。这在行星的赤道附近工作得很好,但是一旦它接近极点,它就会开始爆炸,相机的行为越来越不规则地越靠近极点的中心。

我已经确定这是由于第一个矢量交叉,因为在这种情况下两个矢量彼此接近 - 我不确定这种现象的技术名称是什么。如果第一个向量是0,1,0,则当法线接近0,1,0或0,-1,0时会发生疯狂。

我发现了很多关于这个问题的描述,但没有找到有效的解决方案。我最接近的是:http://xboxforums.create.msdn.com/forums/p/13278/13278.aspx它提到要处理'奇点',在检测到它时使用不同的向量。我可以很容易地确定相机在行星面上何时会发生这种情况(因为我的行星球体是从投射到球面坐标的6个四维树组生成的),但是当我切换到新的矢量时,有一个非常明显的快照。

这是当前的代码:

Vector3 triNormal; //the current normal of the target vertex
Vector3 origin = Vector3.Forward;
Matrix orientation.Forward = origin;

orientation.Up = triNormal;
orientation.Right = Vector3.Cross(orientation.Up, orientation.Forward);
orientation.Right.Normalize();
orientation.Forward = Vector3.Cross(orientation.Right, orientation.Up);
orientation.Forward.Normalize();

我已经尝试过检测triNormal何时位于其中一个极面上,并将'origin'设置为其他内容,例如Right。相机一旦在脸上就会表现正常,但在它穿过时会立即拍到新的旋转。这是有道理的,因为它的参考向量刚刚改变,但需要消除以获得流畅的用户体验。我试图弄清楚如何偏移相机的偏航以使轨道相机抵消新的坐标系,但它似乎不是一个恒定的值,这取决于相机当前瞄准的球体上的位置。我不确定如何计算出差异是什么。

另请注意,因为它在XNA和C#中,我使用的是右手坐标系。

1 个答案:

答案 0 :(得分:0)

我不明白你为什么这样做:

orientation.Forward = Vector3.Cross(orientation.Right, orientation.Up);
orientation.Forward.Normalize();

当您已使用之前的orientation.Forward获取orientation.Right时 (如果你正在“穿越”法线向量,我认为你不需要将它们标准化。)

无论如何,如果triNormal是目标顶点的当前法线,而你的相机正在俯视它,我认为你应该:{/ p>

orientation.Forward = -triNormal