Unity3D中的Quaternion(四元數)

2021-08-01 18:07:54 字數 2745 閱讀 5847

今天,我來總結一下unity中的四元數得使用。我也是初學,就寫的比較飄逸,難免有錯誤!

四元數的概念

四元數,這是乙個圖形學的概念,一般沒怎麼見過,圖形學中比較常見的角位移的表示方法有「矩陣」、「尤拉角」、「四元數」這三種。可以說各有各的優點和不足,不同的場合用不同的方法。其中四元數的優點有:平滑插值、快速連線、角位移求逆、可以與矩陣形式快速轉換、僅用四個數表示。不過,它也有一些缺點:比尤拉角多乙個數表示、可能不合法(如:壞的輸入資料或者浮點數累計都可能使四元數不合法,不過可以通過四元數標準化來解決這個問題)、晦澀難懂。

那為啥四元數是四個數呢?其實還是有個小故事的。話說當時十九世紀的時候,愛爾蘭的數學家hamilton一直在研究如何將複數從2d擴充套件至3d,他一直以為擴充套件至3d應該有兩個虛部(可是他錯了,哈哈)。有一天他在路上突發奇想,我們搞搞三個虛部的試試!結果他就成功了,於是乎他就把答案刻在了broome橋上。說到這裡,也就明白了,四元數其實就是定義了乙個有三個虛部的複數w+xi+yj+zk。記法[w,(x,y,z)]。

好了,上面我們就基本清楚四元數的作用以及好處與坑了,下面開始正式講講unity中我們如何使用一些常見的四元數操作。

unity中的四元數

基本的旋轉,我們可以通過transform.rotate來實現,但是當我們希望對旋轉角度進行一些計算的時候,就要用到四元數quaternion了。quaternion的變數比較少也沒什麼可說的,大家一看都明白。唯一要說的就是xyzw的取值範圍是[-1,1],物體並不是旋轉一周就所有數值回歸初始值,而是兩周。

初始值: (0,0,0,1)

沿著y軸旋**180°(0,1,0,0) 360°(0,0,0,-1)540°(0,-1,0,0) 720°(0,0,0,1)

沿著x軸旋**180°(-1,0,0,0) 360°(0,0,0,-1)540°(1,0,0,0) 720°(0,0,0,1)

無旋轉的寫法是quaternion.identify。

下面我就按照unity的api介紹下四元數相關的幾個基本函式。

一、lookrotation

宣告形式:public static quaternion lookrotation ( vector3 forward, vector3 upwards=vector3.up )

這個功能很實用,傳入的兩個引數分別代表前方盯著的方向以及自己的上方向。它可以讓乙個gameobject轉動腦袋盯著另乙個物體。如:

public transform target;

void update()

這段**就可以讓當前的object時時盯著target不放,當然,你也可以自定義up朝向,這裡預設是vector3.up。

二、angle

宣告形式:public static float angle ( quaternion a, quaternion b )

這個就比較簡單了,它可以計算兩個旋轉之間的夾角。與vector3.angle()作用是一樣的。

三、euler

宣告形式:public static quaternion euler ( float x, float y, float z )

或者:    public static quaternion euler ( vector3 euler )

這個函式可以將乙個尤拉形式的旋轉轉換成四元數形式的旋轉。傳入的引數分別是尤拉軸上的轉動角度。

四、slerp

宣告形式:public static quaternion slerp ( quaternion from, quaternion to, float t )

基本意思就是線性地從乙個角度旋轉到另乙個角度,其中,旋轉勻速增加t。

附加內容:很多時候from 和to都不是固定的,而且上乙個指令碼也不能保證所有角度下的旋轉速度一致。所以我寫了這個指令碼來保證可以應付大多數情況。

transform target;

float rotatespeed = 30.0f;

quaternion wantedrotation = quaternion.fromtorotation(transform.position, target.position);

float t = rotatespeed/quaternion.angle(transform.rotation, wantedrotation)*time.deltatime;

transform.rotation = quaternion.slerp(transform.rotation, target.rotation, t);

這個指令碼可以保證物體的旋轉速度永遠是rotatespeed。如果自身座標和目標之間的夾角是x度,我們想以s=30度每秒的速度旋轉到目標的方向,則每秒旋轉的角度的比例為s/x。 再乘以每次旋轉的時間time.deltatime我們就得到了用來勻速旋轉的t。

五、fromtorotation

宣告形式:public static quaternion fromtorotation ( vector3 from, vector3 to )

它是得到從乙個方向到另乙個方向的旋轉。就是轉乙個方向,就這麼簡單。

六、identity

這個不是乙個函式,它是乙個唯讀的變數。它代表世界座標系或者父物體座標系中的無旋轉方位。

兩點了,累了,睡覺!

Unity3D開發(九) Unity3d流光效果

遊戲開 壇 hello game 遊戲開發群 201276069 之前曾經注意過material 中紋理的屬性都有 tiling 和offset 但沒有深究過其用途,今天才知道竟然可以利用 offset做uv 動畫,從而完成各種有趣的動畫,比如流光效果!流過效果即通常一條高光光在物體上劃過,模擬高光...

unity3D 中Quaternion旋轉演算法

quaternion.euler x,y,z 返回乙個繞x軸旋轉x度再繞y軸旋轉y度再繞z軸旋轉z度的quaternion,因此quaternion.euler 0,90,0 返回乙個繞y軸旋轉90度的旋轉操作。quaternion作用於vector3的右乘操作 返回乙個將向量做旋轉操作後的向量。因...

Unity3D中的shader高階

unity3d shader 基礎知識 unity3d shader 官方教程翻譯 1.unity中配備了強大的陰影和材料的語言工具稱為shaderlab,以程式語言來看,它類似於cgfx和direct3d的效果框架語法,它描述了材質所必須要的一切諮詢,而不僅僅侷限於平面頂點 畫素著色。2.在uni...