unity 关于Rotation和Quaternion的一些问题(欧拉角与四元数,lerp与slerp)

当我们使用unity的时候,面对一个物体,一个不可避免的问题就是:控制物体的旋转。

unity的Transform组件的第二个属性Rotation为我们提供控制物体旋转的功能。在一个物体的Inspector面板中,我们可以看到三个信息(X,Y,Z)。但是unity同时还具有Quaternion(四元数)的功能,所以这里就有必要介绍一下——欧拉角与四元数(我的数学很渣,只是简单的为大家介绍一下),而unity采用这两种方式来表示旋转或者方向都是为了便于储存。


欧拉角(Euler angles):简单来说就是一种定义物体方向的方法

unity 关于Rotation和Quaternion的一些问题(欧拉角与四元数,lerp与slerp)_第1张图片(来自wikipedia:https://en.wikipedia.org/wiki/Euler_angles)

如图所示,为我们展示了欧拉角,包括(α,β,γ)。另外还有一条特殊的绿色线N。对于上图作几点说明:

蓝色坐标系xyz(小写)表示原始或初始坐标系位置(方向);红色坐标系(XYZ)表示旋转后的坐标方向。绿色的线(line of nodes)是xy和XY坐标平面的交线,那么这条线也就同时正交垂直于zZ平面。

α:x与N的夹角;β:z与Z的夹角 γ:N与X的夹角


四元数(Quaternion)

很抱歉,对于四元数的理解,现在我也不是很清楚,只是简单的对unity的Quaternion的几个函数方法进行了简单了解。下面是百度百科的解释,希望对你有所帮助:

四元数是简单的超复数。 复数是由实数加上虚数单位 i 组成,其中i^2 = -1。 相似地,四元数都是由实数加上三个虚数单位 i、j、k 组成,而且它们有如下的关系: i^2 = j^2 = k^2 = -1, i^0 = j^0 = k^0 = 1 , 每个四元数都是 1、i、j 和 k 的线性组合,即是四元数一般可表示为a + bk+ cj + di,其中a、b、c 、d是实数。(百度百科)

关于四元数和欧拉角之间的互相转换,这里就不再赘述,因为看不懂啊,等体会理解后,在为大家讲解


这里有一篇关于Quaternion下函数方法详细介绍:http://blog.sina.com.cn/s/blog_4a2183a60100ngaa.html

说了这么多,其实我想为大家解释的是:下面这样一个问题:unity什么时候用欧拉角,什么时候使用四元数。

在我们的接触中,unity大部分是接受四元数的输入和输出的。比如说,我们想输出Transform组件的Rotation信息。直接这样写:transform.rotation是不行的,你会发现显示的是一组[-1,1]的数值。而需要调用localEulerAngles方法,才会获得我们所熟知的角度表示。总结来说:其实Transform.rotation是存储的四元数信息,而真正的欧拉角需要调用方法才会获得,即Euler Angles存储的Vector3类型的变量。

我们如何在unity中将一个Vector3类型的欧拉角传给四元数形式的rotation呢?我们不需要复杂的数学运行,需要调用Quaternion下面的方法函数即可。

transform.rotation=Quaternion.Euler(x,y,z)或者是transform.EulerAngles=new Vector(0.0,0.0,0.0)


最后,为大家接受一下lerp与slerp的区别

lerp()函数,我们都很了解,进行插值运算,对于物体平移,使用lerp函数,十分方便。这里就不过多说明了,详细请看unity 圣典。然而对于物体旋转方向的插值,效果就不那么理想了。其实unity还为我们提供了另一种插值函数---Slerp。Quaternion.lerp()。关于这个函数在圣典中的说明很短,只解释是球形插值。让人费解。关于这个问题我的理解是,如果想要对物体的旋转进行插值,我们应该选择slerp函数,这个函数利用四元数,对旋转的角度进行插值,(至于更深层次的机制,我也不甚了解,希望大家留言补充)从而能够达到较为理想的效果。另外,还有Quaternion.lerp()函数,这个说是效果也不如slerp。大家可以自行尝试。下面是关于slerp函数的代码解释

static function Slerp (from : Quaternion, to : Quaternion,t : float) : Quaternion 

注意form和to都是Quaternion四元数类型,而不是vector3类型。

Quaternion.Slerp (Quaternion.Euler(rotation_begin),Quaternion.Euler(rotation_end),t); 

Euler()方法是为了将Vector3类型转换成四元数类型。这是slerp函数的参数要求




谢谢大家浏览,不足之处,我会继续改进!




你可能感兴趣的:(unity,函数方法)