zoukankan      html  css  js  c++  java
  • 使用四元数解决万向节锁(Gimbal Lock)问题

    问题

    使用四元数可以解决万向节锁的问题,但是我在实际使用中出现问题:我设计了一个程序,显示一个三维物体,用户可以输入绕zyx三个轴进行旋转的指令,物体进行相应的转动。

    由于用户输入的是绕三个轴旋转的角度,所以很直接的就想到用欧拉角来表示每一个旋转。但是欧拉角会出现万向节锁,所以我使用四元数替代原来的欧拉角,来计算旋转矩阵。但是奇怪的结果出现了,gimbal lock仍然出现,使用四元数和使用欧拉角,程序的表现一模一样。

    原因

    经过一番思考,并参考 Using Quaternions for OpenGL Rotations ,我找到了问题的根源。

    正如回答所说:

    implement Euler angles with quaternions. That's not helping.

    我的程序是这样计算的:

    计算出绕xyz旋转的欧拉角,转化为四元数,再转为旋转矩阵,传给shader计算。每一次用户输入,都会重新计算绕zyx三个轴旋转的角度,然后生成新的四元数,再生成新的旋转矩阵。这样做在使用欧拉角的时候没有什么问题(反正会出现Gimbal lock),但是使用四元数的时候还这样做,就无法避免Gimbal lock樂。因为这样做,用户输入了绕多个轴的旋转,生成的欧拉角自然是绕多个轴的。参考上一篇博文所述,多次旋转叠加没有考虑坐标系的变化,Gimbal lock还是会产生了。

    解决办法是分别计算用户每一次输入的旋转变换矩阵,将每一次的单独的旋转变换矩阵点乘原来的旋转变换矩阵,得到最新的变换矩阵。后续的每一次变换都在这个矩阵的基础上不断的乘,也就是说每一次都是在原来的基础上再加一点点变化,这样就完美解决了GImbal lock 。

    需要说明的是,用四元数生成多个旋转矩阵,进行相乘,其计算的顺序不会对结果有影响,这是四元数和欧拉角之间的显著区别。也是四元数可以解决问题的关键。

    他人的解释如下:

    you just have a quaternion which represents the current orientation of the object. When you decide to apply a rotation to it (of some angle by some axis), you construct a quaternion that represents that rotation by an angle around that axis. Then you right-multiply that quaternion with the current orientation quaternion, producing a new current orientation.

  • 相关阅读:
    技术出身的创业者管理销售团队的七条成功秘笈
    修改MVC的默认T5 template
    Balsamiq Mockups——界面原型设计软件
    在eclipse中安装pydev插件
    torch.nn.Embedding Learner
    七种交叉验证及其代码 Learner
    Noise Contrastive Estimation 前世今生——从 NCE 到 InfoNCE Learner
    论文解读(GraRep)《GraRep: Learning Graph Representations with Global Structural Information》 Learner
    邻接矩阵、度矩阵 Learner
    可逆矩阵与奇异矩阵 Learner
  • 原文地址:https://www.cnblogs.com/psklf/p/5667593.html
Copyright © 2011-2022 走看看