【Unity】Unity 欧拉角、四元数、万向节死锁、四元数转轴角
文章目錄
- 歐拉角(Euler)
- 萬向節
- 歐拉角旋轉特性
- 歐拉角優點
- 歐拉角缺點
- 方位的表達方式不唯一
- 萬向節鎖(Gimbal Lock)
- 四元數(Quaternion)
- 四元數轉軸角
- 四元數優點
- 四元數缺點
- Quaternion類
歐拉角(Euler)
什么是歐拉角?百科上是這樣解釋的:用來確定定點轉動剛體位置的3個一組獨立角參量,由章動角θ、旋進角(即進動角)ψ和自轉角φ組成,為歐拉首先提出而得名。
很難理解吧?其實我們沒有必要把歐拉角想得太復雜。
對于開發者來說,歐拉角就是用一個Vector3變量來記錄物體沿著x、y、z軸的旋轉。注意,雖然這是一個Vector3變量,但它并不是向量,這個變量的x、y、z三個分量是用來描述旋轉的。
歐拉角特點:
- 使用3個角度來保存方位。
- x 與 z沿自身坐標旋轉,y 沿世界坐標旋轉。
- API:Vector3 eulerAngle = this.transform.eulerAngles;
萬向節
萬向節,也叫平衡環架(Gimbal),具有樞紐的裝置,使得一物體能以單一軸旋轉。由彼此垂直的樞紐軸所組成的一組三只平衡環架,則可使架在最內的環架的物體維持旋轉軸不變。常常應用于船上的陀螺儀、羅盤、飲料杯架等。
在飛行器的航行中,進行XYZ三個方向旋轉的旋轉有專業的術語,見下圖:
沿著機身右方軸(Unity中的+X)進行旋轉,稱為pitch,中文叫俯仰。
沿著機頭上方軸(Unity中的+Y)進行旋轉,稱為Yaw,中文叫偏航。
沿著機頭前方軸(Unity中的+Z)進行旋轉,稱為Roll,中文叫桶滾。
歐拉角旋轉特性
歐拉角的旋轉就是沿著萬向節的軸旋轉的。目前人類最常用也最容易理解的方式是先沿著X軸旋轉,再沿著Y軸旋轉,最后沿著Z軸旋轉,最后達到目標旋轉角度。如下圖所示:
這時候可能就有人會有疑問了,為什么不能三個軸同時旋轉呢?
實際上,如果三個軸同時旋轉,將會無法達到你預期的旋轉效果。為什么呢?因為物體是一個整體,當某一個軸進行旋轉時,其他的軸是跟著物體一起動的,如果還是按照原來的旋轉角度旋轉則會隨著其他軸的轉動形成偏移,如下圖所示:
我們想要的其實只是讓箭頭指向我們,但三個軸同時旋轉卻使這個旋轉軌跡劃出了一個不應該有的弧線。
所以我們要了解的是,歐拉旋轉是一定要有順序的。這樣的問題其實是無法避免的,但是我們可以根據物體的旋轉情況對此進行優化,這個優化的方法就是給三個軸指定一個新的層級順序。
當然這并不是真正的解決了問題,只是盡量避免了問題而已。歐拉角的問題是無法徹底解決的,
歐拉角優點
- 僅使用三個數字表達方位,占用空間小。
- 沿坐標軸旋轉的單位為角度,符合人類思考方式。
- 任意三個數字都是合法的,不存在不合法的歐拉角。
歐拉角缺點
方位的表達方式不唯一
對于一個方位,存在多個歐拉角描述,因此無法判斷多個歐拉角代表的唯一是否相同。
例如:
- 角度 0, 5, 0 與角度 0, 365, 0
- 角度 0, -5, 0 與角度 0, 355, 0
- 角度 250, 0, 0 與角度 290, 180, 180
為了保證任意方位都只有獨一無二的表示,Unity引擎限制了角度范圍,即沿x軸旋轉限制在 -90 ~ 90 之間,沿 y 與 z 軸旋轉限制在 0 ~ 360 之間。
萬向節鎖(Gimbal Lock)
當物體沿 x 軸旋轉 ±90°\ \plusmn 90°?±90° ,自身坐標系z軸與世界坐標系y軸將重合,此時再沿y軸或z軸旋轉時,將會失去一個自由度。
Unity的優化方案:在萬向節死鎖的情況下,規定沿z軸完成繞豎直軸的全部旋轉,即此時y軸旋轉為0。
關于萬向節鎖的講解視頻:https://v.youku.com/v_show/id_XNjk1MTkzMTM2.html#paction
在使用歐拉旋轉的情況下,萬向節鎖的情況是無法避免的,為了更好的表示旋轉,Unity引入了四元數的概念。
四元數(Quaternion)
四元數在3D圖形學中代表旋轉,由一個三維向量 /[x,y,z]/ [x, y, z]/[x,y,z] 和一個標量 /w/ w/w 組成。
旋轉軸為 VVV ,旋轉弧度為 θ\thetaθ ,若使用四元數表示,則四個分量為:
x=Sin(θ/2)?V.xy=Sin(θ/2)?V.yz=Sin(θ/2)?V.zw=Cos(θ/2)x = Sin(\theta / 2) * V.x \\ y = Sin(\theta / 2) * V.y \\ z = Sin(\theta / 2) * V.z \\ w = Cos(\theta / 2)x=Sin(θ/2)?V.xy=Sin(θ/2)?V.yz=Sin(θ/2)?V.zw=Cos(θ/2)
四個分量的值都在 -1 到 1 之間。
幾何應用:四元數與向量相乘,可以實現向量的旋轉。
代碼:
// 獲取四元數 Quaternion qt = this.transform.rotation;// 使用四元數做旋轉 this.transform.rotation = Quaternion.Euler(0, 50, 0);// 或者調用Rotation方法實現旋轉 this.transform.Rotation(0, 50, 0);四元數旋轉角度相加需要用 * 乘法,而不是加法。
四元數轉軸角
Transform 中的 rotation 使用的是四元數,有時我們需要獲取 Transform 沿某一個軸旋轉的角度,此時可以用下面的代碼進行計算:
Quaternion q = transform.rotation;// 計算X軸旋轉角度 float angleX = 0; float siny_cosp1 = 2 * (q.w * q.x + q.z * q.y); float cosy_cosp1 = 1 - 2 * (q.y * q.y + q.x * q.x); float radian1 = Mathf.Atan2(siny_cosp1, cosy_cosp1); // 求出弧度 angleX = radian1 * Mathf.Rad2Deg; // 轉化角度 Debug.Log("=============" + angleX);// 計算Z軸旋轉角度 float angleZ = 0; float siny_cosp2 = 2 * (q.w * q.z + q.x * q.y); float cosy_cosp2 = 1 -2 * (q.y * q.y + q.z * q.z); float radian2 = Mathf.Atan2(siny_cosp2, cosy_cosp2); // 求出弧度 angleZ = radian2 * Mathf.Rad2Deg; // 轉化角度 Debug.Log("=============" + angleZ);上述方法適用于物體只在一個軸上做了旋轉的情況,Y軸的計算方法以此類推。
四元數優點
避免萬向節死鎖,完全沿自身軸(而不是全局軸)旋轉。
四元數缺點
難于使用,且存在不合法的數值。
Quaternion類
Unity中提供了Quaternion類來處理四元數相關操作,該類的使用方法可以參考我的另外一篇文章:【Unity】Unity常用類:向量Vector3、四元數Quaternion
本文萬向節部分內容參考了塞北煙云大神的文章,地址如下:https://www.jianshu.com/p/9f45e91a2391
更多內容請查看總目錄【Unity】Unity學習筆記目錄整理
總結
以上是生活随笔為你收集整理的【Unity】Unity 欧拉角、四元数、万向节死锁、四元数转轴角的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网络测试仪的用法
- 下一篇: 小学文化学导数——斜率