1. 程式人生 > 其它 >Unity中的四元數

Unity中的四元數

一.簡介:

  在遊戲中常常需要對物體進行旋轉操作,或者瞭解物體的旋轉朝向,所以需要對物體的旋轉進行描述.對物體的旋轉的描述有以下4種常用方式:

  1.尤拉角:將物體的旋轉拆分為繞x軸旋轉\繞y軸旋轉和繞z軸旋轉三個操作.Unity的Inspector視窗中可以檢視到Transform元件中的旋轉引數,這個引數就是尤拉角

  

  使用尤拉角的方式描述旋轉優點在於非常直觀,易於理解,但是缺點在於同樣的旋轉結果可能會有不同的旋轉描述,同時可能導致萬向節死鎖的問題.

  2.軸-角對:三維空間中的物體旋轉一定能描述為繞著某條軸線旋轉一定的度數.我們使用一個向量描述軸線,使用一個數字描述角度,這樣的描述方式稱為軸角對.軸角對的方式不會產生萬向節死鎖的問題.但是在描述旋轉時,我們會發現旋轉α度和α+n*360度(n∈Z)的結果是一樣的,所以採用這種方式描述旋轉角度仍然需要轉化.同時如果將一個軸-角對的旋轉描述中軸和角都取為原來的相反數,描述的結果仍然是相同的.因此同樣的旋轉,使用軸角對仍然有無數種描述方式,但是我們可以發現雖然描述的角度不同,但是這些角度的三角函式值相同,所以引入三角函式來描述旋轉就可以有效減少同一種旋轉結果的可用描述方式.

  3.四元數:對於給定的旋轉,可以使用軸-角對描述為繞著n=(x,y,z)軸旋轉β度得到,那麼這個旋轉使用四元數可以描述為Q=[cos(β/2),sin(β/2)*n]或者Q=[cos(β/2),sin(β/2)*x,sin(β/2)*y,sin(β/2)*z].顯然四元數使用了三角函式對角度進行描述,至於四元數為什麼是這個公式,讀者可以自行查閱學習四元數公式的數學推導和意義,這裡更多地介紹Unity中和四元數有關的內容.四元數可以看做是軸角對描述方式的一種變形.注意:軸角對轉化為四元數時,軸必須單位化(也就是說n必須是單位向量).

  4.旋轉矩陣.

二.四元數有關的常用API

  1.建立四元數

        //
四元數Q = [cos(β/2), sin(β/2)*x, sin(β/2)*y, sin(β/2)*z] float angle = 60f; float halfAngle = angle / 2 * Mathf.Deg2Rad; //軸角對中的軸必須是單位長度軸 Vector3 axis = new Vector3(1, 0, 0); //直接指定四元數的四個引數,繁瑣且複雜,一般不會使用這種方式 Quaternion q = new Quaternion(Mathf.Sin(halfAngle) * axis.x, Mathf.Sin(halfAngle) * axis.y, Mathf.Sin(halfAngle) * axis.z, Mathf.Cos(halfAngle));
//使用AngleAxis靜態方法指定旋轉角和旋轉軸 Quaternion q2 = Quaternion.AngleAxis(angle,axis);

  2.四元數和尤拉角轉換

        //尤拉角轉化為四元數
        Quaternion q = Quaternion.Euler(60, 60, 0);//使用Quaternion結構體的靜態方法
        var e = q.eulerAngles;//四元數中屬性eulerAngles是四元數對應的尤拉角

  3.四元數的乘法表示旋轉

transform.localRotation *= Quaternion.AngleAxis(60 * Time.deltaTime, (new Vector3(10, 5, 4)).normalized);

  4.單位四元數和四元數插值運算

        //單位四元數對應尤拉角(0,0,0)
        transform.localRotation = Quaternion.identity;
        //插值運算(四元數中線性插值和球形插值差別不大,線性插值相對運算速度較快但是旋轉範圍較大時效果較差,推薦球形插值)
        Quaternion.Lerp(transform.rotation, Quaternion.AngleAxis(60, Vector3.right), .5f);
        Quaternion.Slerp(transform.rotation, Quaternion.AngleAxis(60, Vector3.right), .5f);

  5.計算旋轉朝向LookRotation

        //直接設定物體朝向向量(1,1,1)方向
        transform.localRotation = Quaternion.LookRotation(new Vector3(1, 1, 1));
        //設定物體A朝向物體B方向
        Transform A;
        Transform B;
        A.localRotation = Quaternion.LookRotation(B.localPosition - A.localPosition);

三.四元數運算的意義

  1.四元數相乘:代表旋轉量的疊加.如四元數q1和四元數q2的乘法結果代表旋轉四元數是q1的基礎上旋轉q2得到的旋轉四元數結果.

  2.四元數和向量相乘:代表將向量按照四元數對應的軸和角度進行旋轉.