使用四元数解决万向节锁(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.
使用四元数解决万向节锁(Gimbal Lock)问题的更多相关文章
- 万向节锁(Gimbal Lock)的理解
[TOC] 结论 我直接抛出结论: Gimbal Lock 产生的原因不是欧拉角也不是旋转顺序,而是我們的思维方式和程序的执行逻辑没有对应,也就是说是我们的观念导致这个情况的发生. 他人解释 首先我们 ...
- 万向节死锁 gimbal lock
,如下图一,把灰色箭头想象成是一架飞机,红,绿蓝三个圈看作是三个外围控制器,外圈带动所有里圈运动,里圈的运动不影响外圈. 1,首先,绕Y轴旋转(旋转绿圈),来确定前进的方向.这时红圈与蓝圈都跟着旋转. ...
- Gimbal Lock欧拉角死锁问题
技术背景 在前面几篇跟SETTLE约束算法相关的文章(1, 2, 3)中,都涉及到了大量的向量旋转的问题--通过一个旋转矩阵,给定三个空间上的欧拉角\(\alpha, \beta, \gamma\), ...
- Gimbal Lock
[Gimbal Lock] 万向锁源于欧拉角的是有序处理的.U3D中的序列为: y->x->z.当旋转y时,local坐标系与世界坐标系重合,所以y等于永远按惯性坐标旋转.当x旋转+/-9 ...
- 解决SVN CONNOT VERIFY LOCK ON PATH NO MATCHING LOCK-TOKEN AVAILABLE
最近使用SVN,开发项目的时候,璞玉遇到一个问题.就是: connot verify lock on path no matching lock-token available connot v ...
- 【转】锁(lock)知识及锁应用
sql server锁(lock)知识及锁应用转自:http://blog.csdn.net/huwei2003/article/details/4047191 关键词:锁提示,锁应用 提示:这里所摘 ...
- Synchronized和Lock, 以及自旋锁 Spin Lock, Ticket Spin Lock, MCS Spin Lock, CLH Spin Lock
Synchronized和Lock synchronized是一个关键字, Lock是一个接口, 对应有多种实现. 使用synchronized进行同步和使用Lock进行同步的区别 使用synchro ...
- 自旋锁Spin lock与互斥锁Mutex的区别
POSIX threads(简称Pthreads)是在多核平台上进行并行编程的一套常用的API.线程同步(Thread Synchronization)是并行编程中非常重要的通讯手段,其中最典型的应用 ...
- 同步锁之lock
一. synchronized的缺陷 当一个代码块被synchronized修饰时,同时该代码块被一个线程执行,其他线程便只能一直等待,等待获取锁的线程释放锁,而这里获取锁的线程释放锁只会有两种情况: ...
随机推荐
- JS核心系列:理解 new 的运行机制
和其他高级语言一样 javascript 中也有 new 运算符,我们知道 new 运算符是用来实例化一个类,从而在内存中分配一个实例对象. 但在 javascript 中,万物皆对象,为什么还要通过 ...
- JavaScript 对数据处理的5个API
JavaScript对数据处理包括向上取整.向下取整.四舍五入.固定精度和固定长度5种方式,分别对应ceil,floor,round,toFixed,toPrecision等5个API,本文将对这5个 ...
- TODO:Laravel 使用blade标签布局页面
TODO:Laravel 使用blade标签布局页面 本文主要介绍Laravel的标签使用,统一布局页面.主要用到到标签有@yield,@ stack,@extends,@section,@stop, ...
- TypeScript Vs2013 下提示Can not compile modules unless '--module' flag is provided
VS在开发TypeScript程序时候,如果import了模块有的时候会有如下提示: 这种情况下,只需要对当前TypeScript项目生成设置为AMD规范即可!
- 搭建QQ聊天通信的程序:(1)基于 networkcomms.net 创建一个WPF聊天客户端服务器应用程序 (1)
搭建QQ聊天通信的程序:(1)基于 networkcomms.net 创建一个WPF聊天客户端服务器应用程序 原文地址(英文):http://www.networkcomms.net/creating ...
- 显示本地openssl支持的加密算法
参考页面: http://www.yuanjiaocheng.net/webapi/parameter-binding.html http://www.yuanjiaocheng.net/webapi ...
- IteratorPattern(迭代子模式)
/** * 迭代子模式 * @author TMAC-J * 聚合:某一类对象的集合 * 迭代:行为方式,用来处理聚合 * 是一种行为模式,用于将聚合本身和操作聚合的行为分离 * Java中的COLL ...
- [转载]网站地址栏小图标favicon.ico的制作方法
有人也许会好奇,有的网址前面有个漂亮的小图标而且有的网站图标还会动,这是怎么做到的呢? 如下图所示: 那个小图标有个名字叫favicon.ico,网站图标虽小但可以起到很好的点缀作用,尤其是当浏览者将 ...
- ViewController respondsToSelector 错误的解决方法
原因解析:(来自别人博客分析)某个公共类或系统提供的控件,存在delegate方法,当创建此公共控件的容器类已经销毁,而这个控件对应的服务是在其它run loop中进行的,控件销毁或者需要进行状态通知 ...
- 12个小技巧,让你高效使用Eclipse
集成开发环境(IDE)让应用开发更加容易.它们强调语法,让你知道是否你存在编译错误,在众多的其他事情中允许你单步调试代码.像所有的IDE一 样,Eclipse也有快捷键和小工具,这些会让您感觉轻松许多 ...