四元數(shù)-Quaternion

<p>
回顧一下四元數(shù)中的屬性和方法。
</p>

屬性:

public Vector3 eulerAngles
功能說明 此屬性用來返回或設(shè)置Quaternion實例對應(yīng)的歐拉角
進(jìn)行賦值的方式通常有兩種:

public Transform A, B;
Quaternion rotations=Quaternion.identity;
Vector3 eulerAngle = Vector3.zero;

第一種是將Quaternion實例賦值給transform的rotation 
rotations.eulerAngles = new Vector3(0.0f, speed * Time.time, 0.0f);
A.rotation = rotations;

第二種是將三維向量代表的歐拉角直接賦值給transform的eulerAngles
eulerAngle = new Vector3(0.0f, speed * Time.time, 0.0f);
B.eulerAngles = eulerAngle;

Quaternion類實例方法:

在Quaternion類中涉及的實例方法有SetFromToRotation方法、SetLookRotation方法和ToAngleAxis方法

SetFromToRotation方法

public void SetFromToRotation(Vector3 fromDirection, Vector3 toDirection);
用于創(chuàng)建一個從fromDirection到toDirection的rotation,同樣也不能夠直接對Transform.rotation直接進(jìn)行操作,先對四元數(shù)進(jìn)行旋轉(zhuǎn),然后將四元數(shù)賦值給rotation,例如:

//不可直接使用transform.rotation.SetFromToRotation(v1,v2)方式進(jìn)行設(shè)置
//只能將實例化的Quaternion賦值給transform.rotation。
Quaternion q1 = Quaternion.identity;
q1.SetFromToRotation(v1,v2);
transform.rotation = q1;

首先會把該物體的xyz軸方向和世界坐標(biāo)的xyz一致(即rotation在世界坐標(biāo)系中為0,如果是父對象有旋轉(zhuǎn)的話也不影響),然后旋轉(zhuǎn)的rotation為:V1指向的方向旋轉(zhuǎn)到V2指向的方向:

image.png

A為v1,B為V2,如果B向上移動一定距離,那么C也會朝上旋轉(zhuǎn);

SetLookRotation方法

基本語法
(1) public void SetLookRotation(Vector3 view);
(2) public void SetLookRotation(Vector3 view, Vector3 up);
用來對一個Quaternion實例的朝向進(jìn)行設(shè)置。例如:

Quaternion q1 = Quaternion.identity;
q1.SetLookRotation(v1); //1.
q1.SetLookRotation(v1, v2); //2.
transform.rotation = q1;

q1.SetLookRotation(v1):transform.right垂直于由Vector3.zero、v1、v1.up構(gòu)成的平面,transform.forward為v1向量,下圖中A為v1:

image.png

q1.SetLookRotation(v1, v2):
transform.right垂直于由Vector3.zero、v1和v2這3點構(gòu)成的平面。
v2除了與Vector3.zero和v1構(gòu)成平面來決定transform.right的方向外,還用來決定transform.up的朝向,因為當(dāng)transform.forward和transform.right方向確定后, transform.up方向剩下兩種可能,到底選用哪一種便由v2來影響。transform.up方向的選取方式總會使得transform.up的方向和v2方向的夾角小于或等于90度。

image.png

當(dāng)v1為Vector3.zero時,方法失效,即不要在使用此方法時把v1設(shè)置成Vector3.zero。
<pre>
提示
不可以直接使用transform.rotation.SetLookRotation(v1, v2)的方式來使用SetLookRotation方法,否則會不起
作用。應(yīng)該使用上述代碼所示的方式,首先實例化一個Quaternion,然后對其使用SetLookRotation,最后將其賦給transform.rotation。
</pre>

ToAngleAxis方法

基本語法
public void ToAngleAxis(out float angle, out Vector3 axis);
其中參數(shù)angle為旋轉(zhuǎn)角,參數(shù)axis為軸向量。
功能說明 此方法用于將Quaternion實例轉(zhuǎn)換為角軸表示。
在transform.rotation.ToAngle Axis(out angle, out axis)中,輸出值angle和axis的含義為:要將GameObject對象的rotation從Quaternion.Identity狀態(tài)變換到當(dāng)前狀態(tài),只需要將GameObject對象繞著axis的軸向(指世界坐標(biāo)系中)旋轉(zhuǎn)angle角度即可。通常和靜態(tài)方法AngleAxis (angle : float, axis : Vector3)聯(lián)合使用,使得一個物體的rotation始終和另一個物體的rotation保持一致,例如:

void Update()
    {
        //使用ToAngleAxis獲取A的Rotation的旋轉(zhuǎn)軸和角度
        A.rotation.ToAngleAxis(out angle, out axis);
        //使用AngleAxis設(shè)置B的rotation,使得B的rotation狀態(tài)的和A相同
        //當(dāng)然也可以只使得B與A的axis相同,而angle不同
        //可以在程序運行時修改A的rotation查看B的狀態(tài)
        B.rotation = Quaternion.AngleAxis(angle, axis);
    }

運行效果如下,B會隨著A的旋轉(zhuǎn)保持和A一致:

image.png

Quaternion類靜態(tài)方法

在Quaternion類中主要的靜態(tài)方法有Angle方法、Dot方法、Euler方法、FromToRotation方法、Inverse方法、Lerp方法、LookRotation方法、RotateTowards方法和Slerp方法:

Angle方法:Quaternion實例間夾角

基本語法 public static float Angle(Quaternion a, Quaternion b);
功能說明 此方法用于返回從參數(shù)a到參數(shù)b變換的夾角。需要注意的是,返回的夾角不是某個局部坐標(biāo)軸向變換的夾角,而是GameObject對象從狀態(tài)a轉(zhuǎn)換到狀態(tài)b時需要旋轉(zhuǎn)的最小夾角。

Dot方法:點乘

基本語法 public static float Dot(Quaternion a, Quaternion b);
a●b=|a||b|cos夾角 可以判斷a在b的前方和后方.

Euler方法:歐拉角對應(yīng)的四元數(shù)

基本語法
(1) public static Quaternion Euler(Vector3 euler);
(2) public static Quaternion Euler(float x, float y, float z);
功能說明 此方法用于返回歐拉角Vector3(x,y,z)對應(yīng)的四元數(shù)Quaternion實例。

FromToRotation方法:Quaternion變換

基本語法
public static Quaternion FromToRotation(Vector3 fromDirection, Vector3 toDirection);
功能說明 此方法用來創(chuàng)建一個從參數(shù)fromDirection到toDirection的Quaternion變換。其功能和實例方法SetFromToRotation (fromDirection : Vector3, toDirection : Vector3)相同:
測試代碼如下:

 void Update()
    {
        //使用實例方法
        //不可直接使用C.rotation.SetFromToRotation(A.position,B.position);
        q1.SetFromToRotation(A.position, B.position);
        C.rotation = q1;
        //使用類方法
        D.rotation = Quaternion.FromToRotation(A.position, B.position);
        //在Scene視圖中繪制直線
        Debug.DrawLine(Vector3.zero, A.position, Color.white);
        Debug.DrawLine(Vector3.zero, B.position, Color.white);
        Debug.DrawLine(C.position, C.position + new Vector3(0.0f, 1.0f, 0.0f),
        Color.white);
        Debug.DrawLine(C.position, C.TransformPoint(Vector3.up * 1.5f), Color.white);
        Debug.DrawLine(D.position, D.position + new Vector3(0.0f, 1.0f, 0.0f),
        Color.white);
        Debug.DrawLine(D.position, D.TransformPoint(Vector3.up * 1.5f), Color.white);
    }
AB夾角.png

C和D的旋轉(zhuǎn)角度:

旋轉(zhuǎn)角度.png
Inverse方法:逆向Quaternion值

基本語法
public static Quaternion Inverse(Quaternion rotation);

功能說明 此方法用于返回參數(shù)rotation的逆向Quaternion值。例如,設(shè)有實例rotation=(x,y,z,w),則Inverse(rotation)=(-x,-y,-z,w)。從效果上說,設(shè)rotation.eulerAngles=(a,b,c),則transform.rotation=Inverse(rotation)相當(dāng)于transform依次繞自身坐標(biāo)系的z軸、x軸和y軸分別旋轉(zhuǎn)-c度、-a度和-b度。由于是局部坐標(biāo)系內(nèi)的變換,最后transform的歐拉角的各個分量值并不一定等于-a、-b或-c。
示例:
代碼如下:

 public Transform A, B;
    void Start()
    {
        Quaternion q1 = Quaternion.identity;
        Quaternion q2 = Quaternion.identity;
        q1.eulerAngles = new Vector3(0, -90, 0);
        q2 = Quaternion.Inverse(q1);
        A.rotation = q1;
        B.rotation = q2;
    }

運行后的結(jié)果如下(Cube藍(lán)色為正面):

結(jié)果.png
Lerp方法:線性插值

基本語法
public static Quaternion Lerp(Quaternion from, Quaternion to, float t);
功能說明 此方法用于返回從參數(shù)from到to的線性插值。當(dāng)參數(shù)t≤0時返回值為from,當(dāng)參數(shù)t≥1時返回值為to。此方法執(zhí)行速度比Slerp方法快,一般情況下可代替Slerp方法。

示例:
代碼如下:


public Transform A, B, C, D;
float speed = 0.2f;
void Update()
{
C.rotation = Quaternion.Slerp(A.rotation, B.rotation, Time.time * speed);
D.rotation = Quaternion.Lerp(A.rotation, B.rotation, Time.time * speed);

運行時會發(fā)現(xiàn),C和D會漸漸由A的rotation旋轉(zhuǎn)到B的rotation:

運行結(jié)果.png
LookRotation方法:設(shè)置Quaternion的朝向(和類實例方法SetLookRotation 類似,可以往上查看實例方法)

基本語法
(1) public static Quaternion LookRotation(Vector3 forward);
(2) public static Quaternion LookRotation(Vector3 forward, Vector3 upwards);

其中參數(shù)forward為返回Quaternion的forward朝向。
功能說明 此方法用于返回一個Quaternion實例,使GameObject對象的z軸朝向參數(shù)forward方向(使GameObject的forward為參數(shù)的向量)。此方法與方法SetLookRotation (view : Vector3, up : Vector3 = Vector3.up)功能相同。

RotateTowards方法:Quaternion插值

基本語法
public static Quaternion RotateTowards(Quaternion from, Quaternion to, float maxDegreesDelta);
其中參數(shù)from為起始Quaternion,參數(shù)to為結(jié)束Quaternion,參數(shù)maxDegreesDelta為每幀最大角度值。

功能說明 此方法用于返回從參數(shù)from到to的插值,且返回值的最大角度不超過maxDegreesDelta。此方法功能與方法Slerp相似,只是maxDegreesDelta指的是角度值,不是插值系數(shù)。當(dāng)maxDegreesDelta<0時,將沿著從to到from的方向插值計算。

Quaternion類運算符

在Quaternion類中涉及的運算符運算有兩個Quaternion實例相乘的運算、一個Quaternion實例和一個Vector3相乘的運算。

兩個Quaternion實例相乘的運算

功能說明 此運算符用于返回兩個Quaternion實例相乘后的結(jié)果。設(shè)A和B均為GameObject對象的一個實例,有如下代碼:
B.rotation *= A.rotation;

代碼每執(zhí)行一次,B都會繞著B的局部坐標(biāo)系的z、x、y軸分別旋轉(zhuǎn)A.eulerAngles.z度、A.eulerAngles.x度和A.eulerAngles.y度,注意它們的旋轉(zhuǎn)次序一定是先饒z軸再繞x軸最后繞y軸進(jìn)行相應(yīng)的旋轉(zhuǎn)。另外由于是繞著局部坐標(biāo)系旋轉(zhuǎn),故而當(dāng)繞著其中一個軸旋轉(zhuǎn)時,很可能會影響其余兩個坐標(biāo)軸方向的歐拉角(除非其余兩軸的歐拉角都為0才不受影響)。

一個Quaternion實例和一個Vector3相乘的運算

功能說明 此運算符的作用是對參數(shù)坐標(biāo)點point進(jìn)行rotation變換。例如,設(shè)A為Vector3實例,有如下代碼:

transform.position += transform.rotation *A;
則每執(zhí)行一次代碼,transform對應(yīng)的對象便會沿著自身坐標(biāo)系中向量A的方向移動A的模長的距離。transform.rotation與A相乘主要來確定移動的方向和距離。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,188評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,667評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內(nèi)容