OpenGL学习之路13----相机控制(鼠标操作)

代码放在github上

本文根据教程:ogldev进行扩充学习,一步步从零开始,记录学习历程

到目前为止,我们已经可以将一个物体以任意大小、任意角度和任意位置摆放在世界空间,相关博文链接:
OpenGL学习之路6—-平移,旋转和缩放变换

OpenGL学习之路9—-混合变换

并且可以将我们的相机任意摆放在世界空间,相关博文链接:
OpenGL学习之路11—-相机空间

上一节通过键盘上的方向键,实现了相机在世界空间里位置的移动,相关链接:
OpenGL学习之路12—-相机控制(键盘操作)

这次我们要通过移动鼠标,实现改变相机的目标方向

一、背景知识

1.1 水平倾角和垂直倾角

小时候玩过的一款经典游戏《抢滩登陆战》,我们无法移动,但是可以通过鼠标控制我们的攻击方向,正如下图中的炮:
这里写图片描述
- 假设它在我们的世界坐标中,它可以绕向量(0,1,0)旋转360°,旋转角度称为“水平倾角”,这个(0,1,0)向量叫做垂直轴线(比如转到身后去打背后的敌人)
- 也可以上下倾斜旋转,绕着与地面平行的向量,这个倾角叫做“垂直倾角”,这个向量叫做“水平轴线”

1.2 水平倾角计算target向量

我们从y轴竖直向下看y轴负方向:
这里写图片描述
可以看到根据水平倾角α可以计算target(目标方向向量)

target.x = cosα 
target.y = 0
target.z = sinα

1.3 万向锁现象

根据垂直倾角来计算target向量,需要考虑水平旋转后水平轴线产生变化。 虽然水平轴线可以由垂直轴线和target向量进行叉积后得到,但是会有可能产生一个叫万向锁的现象。

首先我们明确一点假如一个物体初始 旋转(0,0,0),第一次旋转10度到(0,10,0),当在这个位置时想让它旋转到(0,20,0),它不是从(0,10,0)旋转10度到(0,20,0)而是先回到(0,0,0)再旋转到(0,20,0)

如果初始在(0,0,0)要旋转到(10,20,30),我们规定先旋转Z轴,再旋转Y轴,再旋转X轴,即

(0,0,0) -> (0,0,30) -> (0,20,30) -> (10,20,30)

万向锁的概念很好理解:
- 如果你手上有手机,请将手机水平平放置,如下图所示:
这里写图片描述
- 此时给绕Z轴转一个角度,可以发现X轴和Y轴随着手机绕Z轴转动而改变了,再绕Y轴旋转一个角度,再绕X轴旋转一个角度,我们就可以到让手机指向三维空间任意一个方向
- 但是如果绕Z轴旋转一定角度后,在绕Y轴旋转的时候不小心旋转了90°,这时候怎么绕X轴手机都不会立起来,好像被锁在了桌面上
- 然而绕y轴如果不等于90°,就可以使手机旋转指向三维空间任意一个方向

这里产生万向锁的原因就在于第二次旋转了90°,使得第二次旋转后的x轴和没旋转开始时候的Z轴重合了,所以旋转X轴就相当于重复第一次旋转而没进行“抬高”的动作

1.4 四元数解决万向锁问题

定义一个四元数Q为:

Q=xi+yj+zk+w Q = x i + y j + z k + w
i,j,k都是负数且满足

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值