日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

【Unity】Unity 欧拉角、四元数、万向节死锁、四元数转轴角

發(fā)布時(shí)間:2024/3/12 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Unity】Unity 欧拉角、四元数、万向节死锁、四元数转轴角 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • 歐拉角(Euler)
    • 萬(wàn)向節(jié)
    • 歐拉角旋轉(zhuǎn)特性
    • 歐拉角優(yōu)點(diǎn)
    • 歐拉角缺點(diǎn)
      • 方位的表達(dá)方式不唯一
      • 萬(wàn)向節(jié)鎖(Gimbal Lock)
  • 四元數(shù)(Quaternion)
    • 四元數(shù)轉(zhuǎn)軸角
    • 四元數(shù)優(yōu)點(diǎn)
    • 四元數(shù)缺點(diǎn)
    • Quaternion類(lèi)


歐拉角(Euler)

什么是歐拉角?百科上是這樣解釋的:用來(lái)確定定點(diǎn)轉(zhuǎn)動(dòng)剛體位置的3個(gè)一組獨(dú)立角參量,由章動(dòng)角θ、旋進(jìn)角(即進(jìn)動(dòng)角)ψ和自轉(zhuǎn)角φ組成,為歐拉首先提出而得名。

很難理解吧?其實(shí)我們沒(méi)有必要把歐拉角想得太復(fù)雜。

對(duì)于開(kāi)發(fā)者來(lái)說(shuō),歐拉角就是用一個(gè)Vector3變量來(lái)記錄物體沿著x、y、z軸的旋轉(zhuǎn)。注意,雖然這是一個(gè)Vector3變量,但它并不是向量,這個(gè)變量的x、y、z三個(gè)分量是用來(lái)描述旋轉(zhuǎn)的。

歐拉角特點(diǎn):

  • 使用3個(gè)角度來(lái)保存方位。
  • x 與 z沿自身坐標(biāo)旋轉(zhuǎn),y 沿世界坐標(biāo)旋轉(zhuǎn)。
  • API:Vector3 eulerAngle = this.transform.eulerAngles;

萬(wàn)向節(jié)

萬(wàn)向節(jié),也叫平衡環(huán)架(Gimbal),具有樞紐的裝置,使得一物體能以單一軸旋轉(zhuǎn)。由彼此垂直的樞紐軸所組成的一組三只平衡環(huán)架,則可使架在最內(nèi)的環(huán)架的物體維持旋轉(zhuǎn)軸不變。常常應(yīng)用于船上的陀螺儀、羅盤(pán)、飲料杯架等。

在飛行器的航行中,進(jìn)行XYZ三個(gè)方向旋轉(zhuǎn)的旋轉(zhuǎn)有專(zhuān)業(yè)的術(shù)語(yǔ),見(jiàn)下圖:

沿著機(jī)身右方軸(Unity中的+X)進(jìn)行旋轉(zhuǎn),稱(chēng)為pitch,中文叫俯仰。
沿著機(jī)頭上方軸(Unity中的+Y)進(jìn)行旋轉(zhuǎn),稱(chēng)為Yaw,中文叫偏航。
沿著機(jī)頭前方軸(Unity中的+Z)進(jìn)行旋轉(zhuǎn),稱(chēng)為Roll,中文叫桶滾。

歐拉角旋轉(zhuǎn)特性

歐拉角的旋轉(zhuǎn)就是沿著萬(wàn)向節(jié)的軸旋轉(zhuǎn)的。目前人類(lèi)最常用也最容易理解的方式是先沿著X軸旋轉(zhuǎn),再沿著Y軸旋轉(zhuǎn),最后沿著Z軸旋轉(zhuǎn),最后達(dá)到目標(biāo)旋轉(zhuǎn)角度。如下圖所示:

這時(shí)候可能就有人會(huì)有疑問(wèn)了,為什么不能三個(gè)軸同時(shí)旋轉(zhuǎn)呢?
實(shí)際上,如果三個(gè)軸同時(shí)旋轉(zhuǎn),將會(huì)無(wú)法達(dá)到你預(yù)期的旋轉(zhuǎn)效果。為什么呢?因?yàn)槲矬w是一個(gè)整體,當(dāng)某一個(gè)軸進(jìn)行旋轉(zhuǎn)時(shí),其他的軸是跟著物體一起動(dòng)的,如果還是按照原來(lái)的旋轉(zhuǎn)角度旋轉(zhuǎn)則會(huì)隨著其他軸的轉(zhuǎn)動(dòng)形成偏移,如下圖所示:

我們想要的其實(shí)只是讓箭頭指向我們,但三個(gè)軸同時(shí)旋轉(zhuǎn)卻使這個(gè)旋轉(zhuǎn)軌跡劃出了一個(gè)不應(yīng)該有的弧線。

所以我們要了解的是,歐拉旋轉(zhuǎn)是一定要有順序的。這樣的問(wèn)題其實(shí)是無(wú)法避免的,但是我們可以根據(jù)物體的旋轉(zhuǎn)情況對(duì)此進(jìn)行優(yōu)化,這個(gè)優(yōu)化的方法就是給三個(gè)軸指定一個(gè)新的層級(jí)順序。

當(dāng)然這并不是真正的解決了問(wèn)題,只是盡量避免了問(wèn)題而已。歐拉角的問(wèn)題是無(wú)法徹底解決的,

歐拉角優(yōu)點(diǎn)

  • 僅使用三個(gè)數(shù)字表達(dá)方位,占用空間小。
  • 沿坐標(biāo)軸旋轉(zhuǎn)的單位為角度,符合人類(lèi)思考方式。
  • 任意三個(gè)數(shù)字都是合法的,不存在不合法的歐拉角。

歐拉角缺點(diǎn)

方位的表達(dá)方式不唯一

對(duì)于一個(gè)方位,存在多個(gè)歐拉角描述,因此無(wú)法判斷多個(gè)歐拉角代表的唯一是否相同。

例如:

  • 角度 0, 5, 0 與角度 0, 365, 0
  • 角度 0, -5, 0 與角度 0, 355, 0
  • 角度 250, 0, 0 與角度 290, 180, 180

為了保證任意方位都只有獨(dú)一無(wú)二的表示,Unity引擎限制了角度范圍,即沿x軸旋轉(zhuǎn)限制在 -90 ~ 90 之間,沿 y 與 z 軸旋轉(zhuǎn)限制在 0 ~ 360 之間。

萬(wàn)向節(jié)鎖(Gimbal Lock)

當(dāng)物體沿 x 軸旋轉(zhuǎn) ±90°\ \plusmn 90°?±90° ,自身坐標(biāo)系z(mì)軸與世界坐標(biāo)系y軸將重合,此時(shí)再沿y軸或z軸旋轉(zhuǎn)時(shí),將會(huì)失去一個(gè)自由度。

Unity的優(yōu)化方案:在萬(wàn)向節(jié)死鎖的情況下,規(guī)定沿z軸完成繞豎直軸的全部旋轉(zhuǎn),即此時(shí)y軸旋轉(zhuǎn)為0。

關(guān)于萬(wàn)向節(jié)鎖的講解視頻:https://v.youku.com/v_show/id_XNjk1MTkzMTM2.html#paction

在使用歐拉旋轉(zhuǎn)的情況下,萬(wàn)向節(jié)鎖的情況是無(wú)法避免的,為了更好的表示旋轉(zhuǎn),Unity引入了四元數(shù)的概念。

四元數(shù)(Quaternion)

四元數(shù)在3D圖形學(xué)中代表旋轉(zhuǎn),由一個(gè)三維向量 /[x,y,z]/ [x, y, z]/[x,y,z] 和一個(gè)標(biāo)量 /w/ w/w 組成。

旋轉(zhuǎn)軸為 VVV ,旋轉(zhuǎn)弧度為 θ\thetaθ ,若使用四元數(shù)表示,則四個(gè)分量為:
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)
四個(gè)分量的值都在 -1 到 1 之間。

幾何應(yīng)用:四元數(shù)與向量相乘,可以實(shí)現(xiàn)向量的旋轉(zhuǎn)。

代碼:

// 獲取四元數(shù) Quaternion qt = this.transform.rotation;// 使用四元數(shù)做旋轉(zhuǎn) this.transform.rotation = Quaternion.Euler(0, 50, 0);// 或者調(diào)用Rotation方法實(shí)現(xiàn)旋轉(zhuǎn) this.transform.Rotation(0, 50, 0);

四元數(shù)旋轉(zhuǎn)角度相加需要用 * 乘法,而不是加法。

四元數(shù)轉(zhuǎn)軸角

Transform 中的 rotation 使用的是四元數(shù),有時(shí)我們需要獲取 Transform 沿某一個(gè)軸旋轉(zhuǎn)的角度,此時(shí)可以用下面的代碼進(jìn)行計(jì)算:

Quaternion q = transform.rotation;// 計(jì)算X軸旋轉(zhuǎn)角度 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; // 轉(zhuǎn)化角度 Debug.Log("=============" + angleX);// 計(jì)算Z軸旋轉(zhuǎn)角度 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; // 轉(zhuǎn)化角度 Debug.Log("=============" + angleZ);

上述方法適用于物體只在一個(gè)軸上做了旋轉(zhuǎn)的情況,Y軸的計(jì)算方法以此類(lèi)推。

四元數(shù)優(yōu)點(diǎn)

避免萬(wàn)向節(jié)死鎖,完全沿自身軸(而不是全局軸)旋轉(zhuǎn)。

四元數(shù)缺點(diǎn)

難于使用,且存在不合法的數(shù)值。

Quaternion類(lèi)

Unity中提供了Quaternion類(lèi)來(lái)處理四元數(shù)相關(guān)操作,該類(lèi)的使用方法可以參考我的另外一篇文章:【Unity】Unity常用類(lèi):向量Vector3、四元數(shù)Quaternion


本文萬(wàn)向節(jié)部分內(nèi)容參考了塞北煙云大神的文章,地址如下:https://www.jianshu.com/p/9f45e91a2391

更多內(nèi)容請(qǐng)查看總目錄【Unity】Unity學(xué)習(xí)筆記目錄整理

總結(jié)

以上是生活随笔為你收集整理的【Unity】Unity 欧拉角、四元数、万向节死锁、四元数转轴角的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。