欧拉角万向节锁问题

这两天一直纠结在欧拉角的万向节锁问题上,查了很多资料,可是依旧没有完全弄懂这个问题,引用《3D数学基础:图形与游戏开发》一书中的一句话,”如果您从来没有遇到过万向锁情况,你可能会对此感到困惑,而且不幸的是,很难在本书中讲清楚这个问题,你需要亲身经历才能明白。”,认为这个确实需要在以后的实践过程中遇到这个问题时,才会理解地更加透彻.
虽然没有完全弄明白,但还是有一点总结:
(1)万向节锁问题,和具体的旋转顺序相关,例如最常用的ZXY顺序,在X轴旋转为+-90°时,无论Z轴和Y轴的旋转角度如何变化,物体将在某个维度上被锁住这篇文章中第二部分手机旋转的例子比较生动形象;如果此时X轴不是+-90°,那么在X轴不变的前提下,依旧可以通过选取适当的Z轴和Y轴旋转值使物体指向三维空间中的任意方向.
(2)(1)中的锁住并不是很多文章中所说的物体无法通过旋转改变方向了,而是若要改变成某个方向,那么yaw-pitch-roll的角度会发生”突变”,如何理解这种突变呢?借助一个例子来,该例子来源于这篇文章,对于一个炮塔模型,假设地面上的一个炮塔有两个旋转轴:Y(对应于yaw)垂直于地面,使炮塔可以平行地面360°旋转(12点方向为0°);X(对应于pitch)平行于地面,使得炮口可以绕着它上下90°旋转(平行地面设为0°),这里我们省略roll旋转角,因为roll是对炮口本身进行旋转(炮口本身的旋转对于这里的例子没有太大意义,为了简单,故省略),这里的X和Y已经足够表示天空中的任意一点!
这时,一架敌机从3点钟方向飞来,其在炮台坐标系的坐标是XY-(10,-90),Y=-90°的原因是炮口初始对准的是12点方向,需要顺时针旋转90°(以逆时针为正)指向三点方向.飞机保持9点钟的方向飞行,随着飞机逐步向炮台正上方飞来,X不断增大,当飞机恰好飞到炮塔顶端时,即X=90°时(XY-(90,-90)),飞机突然向6点钟方向飞行,且假设其飞至XY-(89, -180),我们发现,简单地转动X轴或者Y轴都无法使得炮口由正上方(89,-90)转到飞机所在的方向,只有先将Y轴顺时针转动90°,再将X轴逆时针转动1°,才能重新指向飞机的位置,我们发现,炮口相比于之前(10,-90)->(90,-90)的方向连续变化,现在却发生了“突变”.那么这种突变的影响是,在飞机由(90,-90)->(89,-180)时,飞机是直线飞行,若炮口继续保持匀速转动,炮口方向在由(90,-90)->(89,-180)时,其过程可能是这样的(90,-90)->(89.8,-108)->(89.6,-126)->(89.4, -144)->(89.2, -162)->(89, -180),如果在坐标系中画出这些点并连接起来,就会发现其近似一根弧线,这样,飞机是直线飞行,但炮口在这段时间内是曲线运动,结果就是这段时候内炮口会丢失目标!上述这个过程在做插值动画时尤为明显(插值过程就是上述的坐标变化过程),而万向节锁的真正问题也在于此!并不是上述链接中说的,炮口方向无法变化.
(3)虽然可以通过修改旋转顺序来改善万向节锁问题(例如Unity里采用的ZXY顺序,就可以确保Y在0~360角度旋转时都不会发生这个问题),但治标不治本,修改旋转顺序只能在某个旋转角上避免出现万向节锁,可是其它角度依旧会有问题;实际上,”任何使用三个数来表达3D方位的系统,若能保证空间的唯一性,就都会遇到这个问题”.解决的办法是,采用四元数,具体课搜索其它博客了解,在这多说一句,四元数理解起来相对欧拉角比较困难,但可以有效解决万向节锁的问题;
(4)欧拉角出现万向节锁的另一个原因是,别名!例如(2)中的炮台,(90,-90)和(90,-180)实际上都是炮口竖直朝上,因此也导致了旋转路径发生偏移!
(5)万向节死锁会导致位置上连续变化 在数值表示上确是非连续的,给定的两个关键帧之间无法平滑过渡.

实际上,自己对于万向节锁以及相关的问题还存在很多困惑,
(1)这篇文章中的数学证明过程无法理解,感觉作者的证明过程有点以结果来证明结果,特别是”Rb = Rr~*Ry*Rr 要得到绕 坐标系E在绕z轴旋转r后的新系E’下的y轴旋转β的旋转矩阵为Rb,可以先应用Rr~这时可以视作在E下,然后使用E下的旋转Ry绕旧的y轴旋转,在应用Rr转回到E’”这一段,完全不知所云!
(2)这篇文章里提及的静态欧拉角和动态欧拉角;
(3)我在草稿上演示旋转过程时,发现对于给定的角度(x1, y1,z1),分别绕X,Y,Z轴以一定的顺序对指定的点或者线段进行旋转时,最终的结果都是(2)中静态欧拉角的结果,但看到的书籍和博客关于这个都是指动态欧拉角的结果,疑惑不解!
(4)物体坐标系和世界坐标系的轴发生重合,为何会导致万向节锁问题?

这些问题困扰了很久,这两天一直在查资料,画图验证,演算,依旧没有完全弄明白,而且弄得心神疲惫,在此做记录,希望以后实践经历丰富后,再逐步解决这些问题!

解决该问题过程中一些不错的博客:
1.Unity 中的旋转
2.【Unity技巧】四元数(Quaternion)和旋转
3.游戏动画中欧拉角与万向锁的理解
4.欧拉角与万向节死锁
5.万向节死锁问题

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值