【Unity】6.8 Quaternion類(四元數)

分類:Unity、C#、VS2015 ide

建立日期:2016-04-20 函數

1、四元數的概念

四元數包含一個標量份量和—個三維向量份量,四元數Q能夠記做: spa

Q=[w,(x,y,z)] code

在3D數學中使用單位四元數來表示旋轉,對於三維空間中旋轉軸爲n,旋轉角度爲a的旋轉,若是用四元數表示,四個份量分別爲: orm

w=cos(a/2) 對象

x=sin(a/2)cos(bx) blog

y=sin(a/2)cos(by) 遊戲

z=sin(a/2)cos(bz) 開發

其中bx、by、bz分別爲旋轉軸的x,y,z份量。 get

從上面的描述中能夠看到四元數表示的旋轉並不直觀。另外,還能夠用歐拉角和矩陣表示旋轉。可是每—種表示方法都有真各自的優缺點,下圖簡單地對這3種旋轉的表示方法進行了對比:

image

因爲3種表示旋轉的方法都有各自的優缺點,因此在開發過程當中須要根據實際需求選擇不一樣的方法。

2、Quaternion類

在Unity中,四元數使用Quaternion類來表示。

下圖是Quaternion類提供的變量:

image

下圖是Quaternion類提供的函數:

image

下面的C#代碼演示瞭如何讓某個遊戲對象(好比Cube)繞Y軸自轉:

float rotateSpeed = 50f; //設置繞y軸自轉的速度

void Update()

{

//繞y軸自轉

transform.rotation =Quaternion.Euler(0f,rotateSpeed*Time.time,0);

}

3、示例

Transform.rotation爲對象在世界座標系下的旋轉,Transform.localRotation爲對象在父對象的局部座標系下的旋轉,這兩個變量的結果類型均爲四元數。所以,只要將四元數的結果賦值給這兩個變量(Transform.rotation或者Transform.localRotation),就能夠設置遊戲對象的旋轉了。

下面經過一些例子說明經過四元數控制旋轉的基本用法。

一、示例1(Demo8_1_ToAngleAxis.unity)

該例子演示如何獲得遊戲對象當前旋轉的角度-軸。

例子中使用的腳本(AngleAxis.cs)以下:

using UnityEngine;
using System.Collections;
public class ToAngleAxis : MonoBehaviour
{
    public float angle = 0.0f;// 旋轉角度
    public Vector3 axis = Vector3.zero;//旋轉軸
    void Start()
    {
        transform.rotation.ToAngleAxis(out angle, out axis);
        print(angle);
        print(axis);
    }
}

效果以下圖所示:

image

二、示例2(Demo8_2_QuaternionExample.unity)

下面一行代碼演示瞭如何先將遊戲對象的旋轉歸零:

transform.rotation = Quaternion.identity;

歸零後,局部座標系的座標軸與世界座標系的座標軸是平行的。

該例子把前面的例子綜合起來,實現了模擬器太陽升起和落下的過程,同時讓對象的前方向朝着target,上方向朝着Vector.up。

效果以下:

image

三、示例3(Demo8_3_CameraLookAt.unity)

該例子將對象的旋轉從from平滑插值到to,以此來模擬攝像機的觀察方向從物體a過濾到物體b的效果。

代碼以下(CameraLookAt.cs文件):

using UnityEngine;
using System.Collections;

public class CameraLookAt : MonoBehaviour
{
    public Transform from;
    public Transform to;

    //相機觀察方向從a過渡到b所需的時間,以秒爲單位
    public float tranTime = 20.0f;

    //用於記錄開始的時間
    private float startTime;

    void Start()
    {
        startTime = Time.time; // 設置開始時間
    }

    void Update()
    {
        //計算用於插值的係數
        var fracComplete = (Time.time - startTime) / tranTime;
        //平滑插值
        transform.rotation = Quaternion.Slerp(from.rotation, to.rotation, fracComplete);
    }

    Transform[] spawnPoints;


}
相關文章
相關標籤/搜索