766游戏网官网Unity中的欧拉旋转

版权声明:本文为博主原创著作,欢迎转载。请保留博主链接:http://blog.csdn.net/andrewfan

766游戏网官网,欧拉角的概念

在写这篇博客在此以前,我搜寻了网上广大关于欧拉角的定义,发现大部分引用自维基百科的概念,我这边也引述一下:

维基百科定义


莱昂哈德·欧拉用欧拉角来讲述刚体在三维欧几里得空间的势头。对于其他条件,一个刚体的大势,是按照顺序,从这标准,做多个欧拉角的转动而设定的。所以,刚体的样子可以用两个为主旋转矩阵来支配。换句话说,任何有关刚体旋转的转动矩阵是由两个主导旋转矩阵复合而成的。
对此在三维空间里的一个规则,任何坐标系的动向,都可以用两个欧拉角来显示。参考系又叫做实验室参考系,是静止不动的。而坐标系则一定于刚体,随着刚体的团团转而旋转。参阅下图。设定xyz-轴为准绳的参考轴。五个欧拉角:
(αβγ),粉色的轴是xyz-轴,紫色的轴是XYZ-坐标轴。称xy-平面与XY-平面的交接为交点线(紫色),用英文字母(N)代表。
zxz顺规的欧拉角可以静态地这样定义:

  • α是x-轴与交点线的夹角,
  • β是z-轴与Z-轴的夹角,
  • γ是交点线与X-轴的夹角。
    766游戏网官网 1

很心痛地,对于夹角的次第和符号,夹角的四个轴的指定,并不曾另外正规。数学家对此没有达成共识。每当用到欧拉角时,我们亟须了然的意味出夹角的逐一,指定其参考轴。
其实,有过多格局可以设定四个坐标系的相对方向。欧拉角方法只是内部的一种。其余,不同的作者会用不同组合的欧拉角来描述,或用不同的名字表示一致的欧拉角。因而,使用欧拉角前,必须先搞好醒目标概念。


顺规

在经典力学里,时常用zxz顺规来设定欧拉角;照着第二个转动轴的轴名,简称为x顺规。此外,还有别种欧拉角组。合法的欧拉角组中,唯一的界定是,任何四个连续的旋转,必须绕着不同的转动轴旋转。因而,一共有12种顺规。例如,y顺规,第二个转动轴是y-轴,时常用在量子力学、核子物经济学、粒子物医学。其它,还有一种顺规,xyz顺规,是用在航空航天工程学;参阅泰特-布莱恩角。


如上两部分均出自维基百科,我由此把顺规特殊挑选出来,是因为第一段定义中行使的顺规与Unity中动用的顺规是不平等的,假使不理顺这或多或少,很容易造成混淆,这会将这些学Unity而查看欧拉角、万向节死锁之类著作的人带向误区。

Unity中的定义

以下内容来自Unity文档中Transform.eulerAngles的概念,本身是一个Vector3,就是一个三维矢量,
各自包含xyz五个参数。

The x, y, and z angles represent a rotation z degrees around the z axis, x degrees around the x axis, and y degrees around the y axis (in that order).

Only use this variable to read and set the angles to absolute values. Don't increment them, as it will fail when the angle exceeds 360 degrees. Use Transform.Rotate instead.

意思就是说:

xyz代表了三个角度,它们定义了一组有序的旋转,即围绕z轴旋转z度,然后围绕x轴旋转x度,然后围绕y轴旋转y度。
你应该只去读取或者直接设置这些数值,不要增加它们,因为当角度超过360度将会失败。应该使用Transform.Rotate去替代执行旋转操作。

解释

出于Unity内部使用四元数去实施旋转,不会蕴藏欧拉角的总共值,由此它说领先360度会战败是可以知晓的,它用四元数执行完运算之后,会更新最后对应的欧拉角数值,而以此结果欧拉角只是代表了等值的团团转变化结果,却胸中无数表示中间经过,由于欧拉角旋转Z轴361度与1度有一致的结果,它便最终只存储了1度,以便于我们着眼和选拔。

Unity中的顺规

特别注意的是,上述文档中表明了Unity使用zxy的顺规,这与维基百科定义是例外的,因而不可能采纳方面这张图片中的旋转来明白。那么大家尝试来打探一下,Unity中的欧拉旋转究竟是怎么的。

欧拉旋转的小试验

此间,我动用Unity制作了一个小试验,可以指定在x+,x-,y+,y-,z+,z-这一个轴一贯旋转一个箭头,见下图。
766游戏网官网 2

  • RotateXX按钮代表旋转指定的轴向XX
  • Applied Angles代表共计的欧拉旋转角
  • Result Angles代表Unity经过四元数总计之后输出的结果欧拉角
  • Slider控制旋转的速度
  • 左边居中的空白框用来展示待旋转的实施项,每一遍使用RotateXX按钮都会发出一个转悠待执行项。
  • Rest用来重置
  • Allow Excute代表是都允许实施当前的待执行项。
  • Once All代表是按梯次执行这一个可实施项仍然有着执行项联合实施。

红绿蓝(RGB)三色分别表示XYZ轴,靠近箭头的五个轴是有些坐标轴,有圆球的一端代表轴的正向。远离箭头的前后左右前后断开的6个半截轴代表了世界坐标轴。轴的正向与局部坐标相同。这便是任何最伊始的气象,物体的全局坐标和局部坐标下的欧拉角都是(0,0,0),也就是没有其它旋转的图景。

这么些小程序可以瞻仰我的Github中的UnityLab/Euler页面https://andrewfanchina.github.io/UnityLabs/Euler/,自己尝试一下就可以理解这些按钮的作用,注意需要使用支持WebGL的浏览器打开,比如[Chrome](http://www.google.cn/chrome/browser/desktop/index.html)或者Firefox(360极速浏览器8.7版本以上貌似也是支持的)。文件较大,网速慢的稍等一小会儿。
亟待专注的是,我在写小程序的时候,刻意使用了增长统计的欧拉角(小程序中的Applied
Angles),也就是说,你所推行的每一趟旋转都被抬高到一个Vector3中,最终被安装到箭头的当下欧拉角,相当于箭头被复位之后,重新履行了最新的欧拉角累计值。举例来说,累加总计的欧拉角(90,90,90)所对应的结果都是平等的,无论你是比照什么顺序点击五个旋转按钮。这样,这些小程序可以效仿从初步状态经历过当前合计的欧拉旋转。

欧拉旋转的旋转轴

前述一贯没有强烈的一个问题,就是大家在缠绕哪一个轴进行旋转?在Unity的合法文档上也没有表精晓这么些题目。
准确地说,Unity中老是执行欧拉旋转,都是行使“当前轴”。
例如在Transform的文档中:


public void Rotate(Vector3 eulerAngles, Space relativeTo = Space.Self);

Description
Applies a rotation of eulerAngles.z degrees around the z axis,
eulerAngles.x degrees around the x axis, and eulerAngles.y degrees
around the y axis (in that order).
if relativeTo is left out or set to Space.Self the rotation is applied
around the transform’s local axes. (The x, y and z axes shown when
selecting the object inside the Scene View.) If relativeTo is
Space.World the rotation is applied around the world x, y, z axes.


以此函数提供了一个可选的周旋空间坐标系参数:

  • Space.Self
    局部坐标系,意味着这次欧拉旋转以物体当前的有的坐标朝向为底蕴出发执行旋转。
  • Space.World
    世界坐标系,意味着这一次欧拉旋转以物体当前的世界坐标朝向为底蕴出发执行旋转。
    最要害的倒不是它有可选的社会风气坐标系,一般而言,常用的旋转都是相对当前有些坐标系执行的。
    最着重的是:在这次欧拉旋转过程中,它的相对轴是始终不变的,不变的,不变的…
    比如说大家可以指定一组欧拉旋转(90,60,30),通过前述的顺规我们清楚,先绕Z轴旋转30度,再绕X轴旋转90度,再绕Y轴转动60度,即使有这么的一一,不过Z旋转后相对X轴、Y轴,都是实践本组欧拉旋转前的非凡轴向,它从不发出变动,所以我称它为“当前轴”。在Unity中的欧拉旋转就是这样定义的,不拔除任何学术中欧拉旋转有不一致的概念形式。由此,执行:

    Transform.Rotate(new Vector3(90,60,30))
    

    和执行

    Transform.Rotate(new Vector3(0,0,30));
    Transform.Rotate(new Vector3(90,0,0));
    Transform.Rotate(new Vector3(0,60,0));
    

的结果是不雷同的。第一种情形,只进行了一组欧拉旋转,第二种情景,执行了三组欧拉旋转,后两组欧拉旋转的相对轴在转悠时一度发出了改变。

利用小程序验证旋转轴

地方的小程序执行的始终只有一组欧拉旋转,它每一回累计欧拉角变化未来,都一定于从起先状态重新履行一起欧拉角的团团转。由此它很容易来阐明相对的旋转轴向。

只要我们设定一组欧拉旋转(90,90,90),其最后的转动结果朝向如下图A。
766游戏网官网 3

这就是说,我们按照Unity定义的顺规,先举办Z轴旋转90度。

766游戏网官网 4

它的旋转轴是先河的+z轴,轨迹记录了此次旋转划过的职位。接着是绕X轴旋转90度。

766游戏网官网 5

它的旋转轴也是从头的+X轴,接着是绕Y轴转动90度。

766游戏网官网 6

它的旋转轴也是开头的+Y轴。最后大家赢得了(90,90,90)这一组欧拉旋转的最终结出,与图A的结果一致。可以看看,它的确是本着起始的固定轴向在拓展按Z、X、Y顺序的团团转。

总结

说到底,我们统计一下Unity中的欧拉旋转。它是沿着Z、X、Y顺规执行的旋转,一组欧拉旋转过程中,相对的轴向不会爆发变化。Transform.Rotate(new
Vector3(90,60,30)),代表履行了一组欧拉旋转,它相对的是旋转前的局部坐标朝向。

正是这种顺规和轴向的定义,它导致了“万向节死锁”的本来形成。
且听下回分解…

发表评论

电子邮件地址不会被公开。 必填项已用*标注