首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我的FPS摄像机在转动?在Python中使用欧拉角(而不是四元数)实现

为什么我的FPS摄像机在转动?在Python中使用欧拉角(而不是四元数)实现
EN

Stack Overflow用户
提问于 2019-02-26 13:05:33
回答 1查看 374关注 0票数 2

我正试图生成一个视图矩阵,这将作为一个FPS相机,但我得到了滚动。共享我的python代码,以防有人发现问题所在:

代码语言:javascript
复制
import numpy as np

class Camera():
    def __init__(self):
        self.sens = np.array([0.002, 0.002])  # mouse sensitivity (x, y)
        self.angpos = np.array([0.0, 0.0])  # (pitch, yaw)

    def mouse_move(self, pos, rel):
        self.angpos = rel[::-1]*self.sens  # mouse relative motion (delta-x, delta-y)
        ya = self.angpos[1]
        yrot = np.array([
            [ np.cos(ya),  0.0,    np.sin(ya),   0.0],
            [ 0.0,         1.0,    0.0,          0.0],
            [-np.sin(ya),  0.0,    np.cos(ya),   0.0],
            [0.0,          0.0,    0.0,          1.0]
        ])

        xa = self.angpos[0]
        xrot = np.array([
            [ 1.0,    0.0,          0.0,          0.0 ],
            [ 0.0,    np.cos(xa),  -np.sin(xa),   0.0 ],
            [ 0.0,    np.sin(xa),   np.cos(xa),   0.0 ],
            [ 0.0,    0.0,          0.0,          1.0 ],
        ])

        return yrot @ xrot  # view matrix


# this is the callback for mouse movement. `pos` is absolute mouse 
# position in the screen and `rel` is the position relative to previous call
# def mouseMotionEvent(self, pos, rel):
#     view = self.cam.mouse_move(pos, rel)  # self.cam is an instance of Camera
#     self.view = view @ self.view
#     return True

下面是我得到的一些行为:

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-02-26 13:29:26

抽象地说,你的问题是,由俯仰和偏航引起的旋转在构图中并不是封闭的。

更具体地说:想象一下控制第一人称摄像机。往下看,然后向左和右转。当你直视前方时,你的观点将以一种截然不同的方式移动。然而,你的计算,表现得就像摄像机一样。

每一个滴答,你把view从右边乘以一个偏航矩阵,然后是一个基音矩阵。这意味着过一段时间,您的视图矩阵将是许多音调矩阵和偏航矩阵的交替乘积。然而,音高和偏航矩阵不通勤。你真正想要的是在所有偏航矩阵的左边(或者右边,取决于你是让你的视图矩阵从左还是右操作,以及你的矩阵是代表视图到全局还是全局到视图的转换)。

因此,快速解决这个问题的方法是编写view = yrot @ view @ xrot。这样的话,所有的y旋转都会在x旋转的左边结束,一切都会好起来的。好吧,至少有一段时间,但是您的视图矩阵最终可能会累积舍入错误,视图可能会滚动、倾斜或更糟。

我建议您不要重用视图矩阵。相反,只需存储玩家当前的俯仰和偏航,在鼠标运动时更新它,然后每次从俯仰和偏航中直接重新计算视图矩阵。这样你也可以以其他方式使用音高和偏航(例如,你想把音高夹在一定的范围内,以防止玩家倒立或翻筋斗),你也不会在你的矩阵中积累错误。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54886220

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档