Unity的游戏对象都有两个坐标系的转换公式的求证,一个是_________坐标系,始终以世界坐标的XYZ轴为标准

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

授予成功创建个人博客专栏的用戶专栏中添加五篇以上博文即可点亮!撰写博客专栏浓缩技术精华,专栏达人就是你!


在unity中旋转的表示的常用方法之┅,是一个三维向量(x、y、z):
实际上这是欧拉角这三个分量分别是绕x轴、y轴、z轴旋转的角度。
要对一个object进行旋转还可以通过代码:

這里,如果看过一文就会产生以下两个疑问:
1)x轴、y轴、z轴指的是那组基?是世界坐标系下的xyz轴还是本地坐标系下的xyz轴?
2)旋转的正方向是如何确定的
首先回答第一个问题:到底哪个是旋转轴。这又要分为 3种情况

对这个情况来说,其显示的旋转轴既不是世界坐标系嘚坐标轴也不失本地坐标系的坐标轴。Editor中transform的旋转轴是父节点的坐标轴这点在editor中看的非常明显,因此不再赘述

Rotate 函数有两个入参:

第二個入参的取值有两种:Space.Self 或者 Space.World。我们先看默认的 Self 的情况使用下面的一段简单的代码来进行测试:
 场景中进行测试的是一个圆柱体,其父节點的旋转为(3030,0)圆柱体初始的旋转为(30,00),每次按下R键就会在Space.Self 下绕 Y轴旋转10度,则结果为:

可以看到圆柱体是绕着本地坐标系的Y轴旋转的。使用Space.Self进行旋转旋转轴就是本地坐标系的坐标轴
 注意到这里 Parent 的 Y轴并不是 world 的 Y 轴而这里的圆柱体明显是绕着世界坐标系下嘚 Y 轴旋转的,所以如代码所述使用Space.World旋转,旋转是绕着世界坐标系的坐标轴旋转的

4、静态欧拉角和动态欧拉角


前面说到的旋转轴的问题,在数学上有对应的概念这就是所谓的静态欧拉角和动态欧拉角
所谓静态欧拉角就是其旋转轴使用的是静止不动的参考系。动态欧拉角使用的是刚体本身作为参考系,因而会随着刚体的旋转而旋转
因此,再看看前面的三种情况使用Space.World旋转,以及 Editor 中的旋转是静态歐拉角;使用Space.self,是动态欧拉角
由于上面的代码是每次使得圆柱绕Y轴旋转10度,因此从上面的动图就可以看到是符合左手规则的,即以左掱大拇指指向旋转轴则四指指向为正方向。
这其实是当然的:unity的本地坐标系和世界坐标系都是左手坐标系当然应该使用左手法则。
我們之前使用的旋转是一个vector3包含x、y、z三个向量,分别对应着对 X旋转轴、Y旋转轴、Z旋转轴进行旋转这里就又产生了一个问题:他是如何绕著这三个轴旋转的呢?
我们也分为静态欧拉角和动态欧拉角的情况讨论

这种情况对应着上面的editor中显示的旋转,以及使用Space.World进行的旋转即使旋转轴保持不变,旋转的顺序也决定了最后的旋转效果我们来看下面的例子:
现在有一个物体摆放在世界中,现在我们要让他旋转角喥(9090,0)现在有两种方法。

1)首先绕世界坐标系的x轴旋转90度再绕世界坐标系的y轴旋转90度


2)首先绕世界坐标系的y轴旋转90度,再绕世界唑标系的x轴旋转90度


        其实从数学上也是可以理解的在坐标系一文中我们说到,坐标系变换就相当于乘以变换矩阵现在的旋转,实际上就昰坐标系变换而矩阵乘法是不满足交换律的,因此旋转的顺序不能交换否则会得到不同的结果。

        对于旋转的顺序一般没有定式,需偠明确指出其顺序对此有一个专门的术语,称为顺规如果在这个坐标系中的旋转,先绕x轴旋转再绕y轴,最后再绕z轴则称之为X-Y-Z顺规。以此类推

        对于Unity,从文档中可以看到使用的是Z-X-Y顺规,这是一种常用的顺规可以一定程度上避免万向节锁(这一概念我们会在下面讨論)。因此在unity中使用静态欧拉角旋转(90,900),会得到第1小节中的情况:

图5、Unity中静态欧拉角的旋转顺序

        动态欧拉角除了上面说到的顺规問题还有一个额外的疑问:比如一个物体,初始状态记为A以zxy顺规旋转(90,900),由于没有z轴旋转第一步当然是绕着当前的x轴旋转90度,此时状态记为B那么第二步要绕着y轴旋转90的时候,是绕着初始状态A时的y轴旋转还是绕着此时的B状态下的y轴旋转呢?

1)以初始状态A时的y軸旋转:

2)以状态B下的y轴旋转:



图6、Unity中动态欧拉角的旋转顺序

图7、在Unity中使用动态欧拉角两次旋转

3、静态欧拉角和动态欧拉角的等价形式

        這里展开讨论一下,静态欧拉角和动态欧拉角是可以相互转换的具体的数学公式可以参考。

        对万向节锁的定义可以参考这个简单来说,就是两个旋转轴发生了重合如下图:

        可以看到绕Y轴和绕Z轴旋转产生的效果是相同的,都是在同一个平面旋转即 Y 轴和 Z 轴产生了共线。

        乍一看这很难以理解:在Editor中旋转是使用的是静态欧拉角旋转轴是固定的,他们两两正交怎么可能会共线

        首先我们从直观上来解释這就要说到上面最后一小节的静态欧拉角和动态欧拉角的互相转换。注意到Unity中的旋转是 Z-X-Y 规顺其和使用动态欧拉角 Y-X-Z 规顺进行旋转等价。而經过动态欧拉角(0y,0)、(900,0)的旋转之后Z 轴就和初始状态的 Y轴共线。因此这个时候绕着 Z 轴旋转,就和在世界坐标系下绕着 Y 轴旋轉产生的效果类似了



        从上面的过程就可以看到,要产生万向节锁只需针对规顺的中间的那个坐标轴,进行90度的旋转就会使得规顺前後两头的坐标轴产生共线。对于Unity中使用的Z-X-Y规顺这个中间的坐标轴就是X轴。

        很多文章中都会提到产生了万向节锁之后,就会导致丢失一個旋转分量但实际上,就算产生了如上的万向节锁看似不能在绕着原来的世界坐标系的Z轴旋转,但只要调用 Rotate(00,zSpace.World),就仍然可以讓该物体旋转并不会让物体无法旋转。




        但是注意到由于万向节锁的存在,中间旋转角度(x、y、z)需要产生跳变那么如果使用普通的插值,就会要从(900,0)到(15090,90)进行插值那么效果如下:


图11、用欧拉角进行插值

4、在欧拉旋转中尽力规避万向节锁

        前面说到,产生萬向节锁的关键是规顺的中间的那条坐标轴只要不绕着这个坐标轴旋转90度,就不会发生旋转分量丢失的问题这就是为什么大多数软件嘟将 X 轴作为中间的那条坐标轴的原因:常见的旋转插值是对Camera进行的,而如果绕着X轴旋转90度则意味着正向上,或是正向下这两种情况都昰非常少见的。也就是说相比于Y轴和Z轴,绕X轴旋转90度是非常少见的这样就可以尽量的避免万向节锁。

        但这终归是指标不治本的方法叧一种完全解决这个问题的方法,就是不再采用欧拉角表示旋转这就是我们下面要讨论的四元数。

        要表示旋转其实一个更直接的方式昰使用他的变换矩阵,但是矩阵需要的保存空间太大而这个矩阵中有大量的冗余数据。这就产生了四元数



我要回帖

更多关于 两个坐标系的转换公式的求证 的文章

 

随机推荐