怎么能简单地调用间距()和偏航()会导致相机最终卷()?
题
我编码一个基本的OpenGL游戏,我已经得到了一些代码,处理鼠标在移动相机的条款。
我使用下面的方法:
int windowWidth = 640;
int windowHeight = 480;
int oldMouseX = -1;
int oldMouseY = -1;
void mousePassiveHandler(int x, int y)
{
int snapThreshold = 50;
if (oldMouseX != -1 && oldMouseY != -1)
{
cam.yaw((x - oldMouseX)/10.0);
cam.pitch((y - oldMouseY)/10.0);
oldMouseX = x;
oldMouseY = y;
if ((fabs(x - (windowWidth / 2)) > snapThreshold) || (fabs(y - (windowHeight / 2)) > snapThreshold))
{
oldMouseX = windowWidth / 2;
oldMouseY = windowHeight / 2;
glutWarpPointer(windowWidth / 2, windowHeight / 2);
}
}
else
{
oldMouseX = windowWidth / 2;
oldMouseY = windowHeight / 2;
glutWarpPointer(windowWidth / 2, windowHeight / 2);
}
glutPostRedisplay();
}
然而,在圈子里,你会发现环顾四周后,相机开始“滚”(旋转)。由于我只有打电话俯仰和偏航,我不明白这是怎么可能的。
下面是代码我用我的相机类: http://pastebin.com/m20d2b01e
据我所知,我的相机“滚动”不应该发生。它应该只是球场上下或偏航左右。 NOT滚动。
什么引起的?
解决方案
恭喜 - 你已经发现李群理论!
是,这是可能的。一系列转换的结果 取决于在他们执行的顺序。做一个音高 其次偏航是不一样的做了偏航,随后 由间距。事实上,在无穷小的雅司病的极限 和间距,所不同的相当于一个纯辊;一般 情况下是一个小更复杂。
(物理学家称之为“的换向的关系 旋转基团”。)
如果你熟悉的旋转矩阵,你能做出来 很容易。
其他提示
好吧,如果你开始期待水平地平线,上仰90度,然后向左偏转90度,然后下俯90度,你会看在同一个方向,你开始,但地平线上会是垂直的(仿佛你轧制90度左)。
修改强>:我认为问题在于,偏航/俯仰/翻滚将是适当的,如果相机被处理像飞机。什么你可能想要做的就是把它像一个球一个点,跟踪在那里的球你都指向相机。相反,偏航/俯仰,使用球面坐标跟踪THETA(纬度)和phi(经度)。他们可能听起来很相似,但是考虑到本照相机的直接指向了极端的情况。随着偏航/俯仰,你仍然可以自由调节从直线上升的方向偏航和变桨。随着THETA /皮皮,你只能调整THETA向下,不管你是多么调整披,减少THETA仍然会给你的相机平行于地平线。这是怎样的FPS相机的工作(你不能这么远了,你正在寻找你身后看)。
修改2 强>:寻找在你连接到相机代码,要被使用的 rotLati(float angle)
和<强> rotLongi(float angle)
强>功能
在数学上这样做的原因是,在三维空间中的旋转不通勤。这也就意味着,间距(),其次是偏航()是不一样的,然后间距()偏航(),但这一事实的结果是,三种转是密不可分的,你不能执行任何他们两个人没有得到一些三分之一。换句话说,间距()ES和偏航的任何序列()秒将产生显着的辊()效果随着时间的推移,除非序列的第二半是上半场的正好相反。 (还有很多参与这个相当复杂的数学,但细节不是特别相关)
俯仰/偏航/卷都是相对于你的车的方向。当球场上/下,你改变你的偏航轴线。同样,当你偏航,你改变你的俯仰轴。因此,它可能改变你的方向,在短短的一个组合和俯仰偏航和演习类似于螺旋机动的方式。
我相信这种情况被称为万向锁 - 有它的插图上的示例维基百科页面。