OpenGL总结9-万向锁

在使用OpenGL进行模型旋转的时候一个比较经典的问题就是万向锁,这是在使用OpenGL的旋转函数时会面临的问题。

glRotatef(rot,x,y,z);

这是OpenGL的旋转函数,第一个参数代表角度,其余参数分别代表旋转轴x,y,z。正常情况下,选择绕一个轴旋转是没有问题的,不管怎么旋转都是符合我们的预期的。但是当使用多个轴的时候就会出现问题,首先我们需要通过二维的坐标来控制三维的旋转,这就相当于我们少了一维坐标,那么第三维必须要通过一定的计算来得到旋转的信息。

在利用glRotate进行旋转时,使用的是欧拉角,在旋转的过程中坐标轴也会跟随旋转,这样在旋转一定的角度后会失去一个轴,其中的两个轴会重叠,也就是其中的一个方向会被锁定,这样当在二维空间拖动鼠标时就会只有两个轴有反应,自然也就会产生不符合我们预期的旋转。

现在针对万向锁的一般解决方法是利用四元数,四元数是由一个三维向量和一个旋转角组成(x,y,z,w),我的理解是四元数不像欧拉角单独绕某个轴进行旋转,四元数是利用一个三维向量计算出一个新的轴,然后绕这个轴来旋转,并且四元数需要保存旧的旋转,以便在旧的旋转的基础上进行新的旋转。

四元数利用乘法来表示旋转

q1 * q2 =(w1*w2 - x1*x2 - y1*y2 - z1*z2) +
		 (w1*x2 + x1*w2 + y1*z2 - z1*y2) i +
		 (w1*y2 - x1*z2 + y1*w2 + z1*x2) j +
		 (w1*z2 + x1*y2 - y1*x2 + z1*w2) k

每一次新的四元数乘以旧的四元数得到4x4的矩阵,这个矩阵就是旋转后的结果,不过要注意旋转的顺序,前乘与后乘顺序是不同的的,pq代表先旋转q后旋转p。在OpenGL中也经常会遇到矩阵相乘先后的问题,不同的顺序结果是不同的。

另外,四元数还有一个优势,是可以进行插值。
在这里插入图片描述
首先,我们在屏幕上移动的是一个弦,也就是直线,因为屏幕是二维的。虽然我们的移动速度是相同的,但是角度的速度却不是恒定的。所以为了让角度恒定,我们会将直线移动映射到球面的弧度上,也就是进行球面插值。(arcball轨迹球就是非常经典的万向锁解决办法,其中就用到了球面的映射相关的内容)

这样通过四元数计算得到的矩阵就不存在万向锁问题了。

以上内容仅供总结记录。

关于四元数更加详细的内容可以参考以下。

参考

彻底搞懂四元数

发布了19 篇原创文章 · 获赞 0 · 访问量 397
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 1024 设计师: 上身试试

分享到微信朋友圈

×

扫一扫,手机浏览