Unity入門學習(四)3D數學(4)之四元數Quaternion

目錄

一、什么是四元數

二、和歐拉角的關聯以及為什么會出現四元數

三、四元數的基本組成

Unity中的表示:

四、四元數Quaternion這個類中具有的屬性和方法

常用屬性

核心方法

五、四元數之間的計算

1. 叉乘(組合旋轉)

2. 點積(相似度)

六、總結

四元數?Quaternion?屬性與方法總結

詳細說明

1. 屬性

2. 方法

3. 運算符與靜態方法


一、什么是四元數

定義
????????四元數(Quaternion)是一種數學工具,用于表示三維空間中的旋轉。它由四個分量組成:一個實部(w)和三個虛部(x, y, z),數學表達式為:
????????????????????????????????????????q=w+xi+yj+zk
其中?

????????????????????????????????i^{2} + j^{2} + k^{2} = ijk = -1

? ? ? ? 你可以想象四元數是一個“方向標記”,而歐拉角是“分解成三個步驟的轉動角度”。四元數通過一種緊湊的數學形式直接描述方向,避免了歐拉角的分步旋轉可能導致的萬向節死鎖問題。

Unity中的應用????????
????????在Unity中,所有Transform組件的旋轉底層均由四元數實現。雖然開發者通常通過歐拉角(如Inspector面板中的Rotation)調整物體朝向,但Unity會自動將其轉換為四元數存儲。

二、和歐拉角的關聯以及為什么會出現四元數

歐拉角的局限性
????????萬向節死鎖(Gimbal Lock):當繞某一軸旋轉90度時,另外兩個軸的旋轉會重合,導致丟失一個自由度。就是說當你轉到90度時,你想單獨再沿著某一條軸進行旋轉,發現怎么都不可以
例如:飛機俯仰90度后,偏航和滾轉將繞同一軸旋轉,無法獨立控制。
插值不平滑:直接對歐拉角插值會導致旋轉路徑不自然(如抖動或突變)。

四元數的優勢
無萬向節死鎖:四元數通過四維空間描述旋轉,避免了三維歐拉角的軸順序問題。
平滑插值:支持球面線性插值(Slerp),保證旋轉路徑的最短性和平滑性。
計算高效:旋轉合成和逆運算更高效,適合實時計算。

關聯
轉換關系:歐拉角可通過Quaternion.Euler()轉換為四元數,反之通過Quaternion.eulerAngles屬性獲取。
?

三、四元數的基本組成

四元數構成
一個四元數包含一個標量和一個3D向量
[w,v],w為標量,v為3D向量
[w,(x,y,z)]
對于給定的任意的一個四元數:
表示3D空間中的一個旋轉量

軸-角對
在3D空間中 任意旋轉都可以表示 繞著某個軸旋轉一個旋轉角得到

注意:該軸并不是空間中的xyz中軸 而是任意一個軸
對于給定旋轉 假設為繞著n軸 旋轉β角度 n軸為(x,y,z)
那么可以構成的四元數為:
四元數Q = [cos(β/2),sin(β/2)n]
四元數Q = [cos(β/2,sin(β/2)x,sin(β/2)y,sin(β/2)z]

四元數Q則表示繞著軸n,旋轉β度的旋轉量

單位四元數
單位四元數表示沒有旋轉量(角位移)
當角度為0或者360度時
對于給定的軸都會得到單位四元數

[1,(0,0,0)]和[-1,(0,0,0)]都是單位四元數
表示沒有旋轉量

Unity中的表示:

Quaternion q = new Quaternion(x, y, z, w);
// 注意:Unity的構造函數參數順序為(x, y, z, w)

例如:繞Y軸旋轉90度的四元數:

Quaternion rotation = Quaternion.Euler(0, 90, 0);
// 等效于手動計算:
float angle = 90 * Mathf.Deg2Rad;
Quaternion q = new Quaternion(0, Mathf.Sin(angle/2), 0, Mathf.Cos(angle/2));

四、四元數Quaternion這個類中具有的屬性和方法

常用屬性
屬性說明
identity單位四元數(無旋轉)。
eulerAngles轉換為歐拉角(只讀)。
核心方法
方法說明示例
AngleAxis創建繞指定軸旋轉角度的四元數。Quaternion.AngleAxis(90, Vector3.up)
Euler將歐拉角轉換為四元數。Quaternion.Euler(0, 90, 0)
Slerp球面線性插值(平滑旋轉)。Quaternion.Slerp(a, b, t)
Lerp線性插值(速度更快,但路徑非最短)。Quaternion.Lerp(a, b, t)
Inverse返回反向旋轉的四元數。Quaternion.Inverse(rotation)
LookRotation生成朝向某個方向的旋轉。Quaternion.LookRotation(direction)

詳細解釋:

屬性:

(1)identity:單位四元數(無旋轉)
表示“不旋轉”的狀態,常用于初始化旋轉或重置物體方向。

using UnityEngine;public class QuaternionExample : MonoBehaviour
{void Start(){// 將物體旋轉重置為初始狀態(無旋轉)transform.rotation = Quaternion.identity;}
}


(2)eulerAngles:將四元數轉換為歐拉角
返回當前四元數對應的歐拉角(只讀屬性),常用于調試或顯示直觀角度。

using UnityEngine;public class QuaternionExample : MonoBehaviour
{void Update(){// 實時輸出物體的歐拉角Debug.Log("當前歐拉角:" + transform.rotation.eulerAngles);// 注意:直接修改 eulerAngles 可能導致問題,應通過 Quaternion.Euler() 設置// transform.eulerAngles = new Vector3(0, 90, 0); // 不推薦}
}

方法:

(1) AngleAxis:繞指定軸旋轉指定角度
創建繞某個軸旋轉一定角度的四元數,常用于自由軸旋轉。

using UnityEngine;public class QuaternionExample : MonoBehaviour
{public float rotateSpeed = 90f; // 每秒旋轉90度void Update(){// 繞Y軸旋轉(按每秒 rotateSpeed 度旋轉)float angle = rotateSpeed * Time.deltaTime;Quaternion rotation = Quaternion.AngleAxis(angle, Vector3.up);transform.rotation = rotation * transform.rotation;}
}

(2) Euler:歐拉角轉四元數
將歐拉角轉換為四元數,避免直接操作 eulerAngles 導致的問題。

using UnityEngine;public class QuaternionExample : MonoBehaviour
{void Start(){// 設置物體繞Y軸旋轉90度Quaternion targetRotation = Quaternion.Euler(0, 90, 0);transform.rotation = targetRotation;}
}

(3) Slerp:球面線性插值
沿球面最短路徑平滑插值,適合攝像機跟蹤或自然旋轉。

using UnityEngine;public class QuaternionExample : MonoBehaviour
{public Transform target; // 拖入目標物體public float speed = 0.5f;void Update(){// 計算目標方向Vector3 direction = target.position - transform.position;Quaternion targetRotation = Quaternion.LookRotation(direction);// 使用Slerp平滑旋轉transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);}
}
//先快后慢
//A.rotation = Quaternion.Slerp(A.rotation,target.rotation,Time.deltaTime);//勻速變化
//time += Time.deltaTime;
//B.rotation = Quaternion.Slerp(start,target.rotation,time);

效果:物體會平滑轉向目標物體,路徑無抖動。?

(4) Lerp:線性插值
快速插值但路徑非最短,適合對平滑性要求不高的場景。

using UnityEngine;public class QuaternionExample : MonoBehaviour
{public Transform target;public float speed = 1f;void Update(){Quaternion targetRotation = Quaternion.LookRotation(target.position - transform.position);transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, speed * Time.deltaTime);}
}

(5) Inverse:反向旋轉
獲取當前旋轉的逆旋轉,常用于坐標系轉換或相對旋轉。

using UnityEngine;public class QuaternionExample : MonoBehaviour
{public Transform otherObject;void Update(){// 計算當前旋轉的逆旋轉Quaternion inverseRotation = Quaternion.Inverse(transform.rotation);// 將另一個物體的旋轉設置為當前物體的逆旋轉otherObject.rotation = inverseRotation;}
}

效果otherObject?會始終與當前物體保持反向旋轉。?

(6) LookRotation:朝向某個方向
使物體正面朝向指定方向,常用于控制角色或攝像機。

using UnityEngine;public class QuaternionExample : MonoBehaviour
{public Vector3 targetDirection = Vector3.forward; // 默認朝前void Update(){// 動態讓物體朝向 targetDirection 方向Quaternion targetRotation = Quaternion.LookRotation(targetDirection);transform.rotation = targetRotation;}
}

效果:物體正面始終指向?targetDirection(可修改為鼠標或目標位置)。?

完整臻享版:

using UnityEngine;public class QuaternionDemo : MonoBehaviour
{public Transform target;public float rotateSpeed = 90f;public float slerpSpeed = 0.5f;void Start(){// 初始化無旋轉transform.rotation = Quaternion.identity;}void Update(){// 1. AngleAxis 持續繞Y軸旋轉float angle = rotateSpeed * Time.deltaTime;Quaternion rotation = Quaternion.AngleAxis(angle, Vector3.up);transform.rotation = rotation * transform.rotation;// 2. LookRotation 朝向目標if (target != null){Vector3 direction = target.position - transform.position;Quaternion targetRot = Quaternion.LookRotation(direction);transform.rotation = Quaternion.Slerp(transform.rotation, targetRot, slerpSpeed * Time.deltaTime);}// 3. 輸出當前歐拉角Debug.Log("當前歐拉角:" + transform.rotation.eulerAngles);}
}

五、四元數之間的計算

1. 叉乘(組合旋轉)

四元數乘法表示旋轉的疊加,順序為從右到左應用。
公式

????????????????????????q_{result} = q_{1} \times q_{2}

注意啊不滿足交換律:即:

???????????????????????????????q_{1} \times q_{2} \neq q_{2} \times q_{1}

Quaternion qY = Quaternion.Euler(0, 90, 0); // 繞Y軸轉90度
Quaternion qX = Quaternion.Euler(90, 0, 0); // 繞X軸轉90度// 順序1:先繞Y軸轉,再繞X軸轉
transform.rotation = qX * qY;// 順序2:先繞X軸轉,再繞Y軸轉
transform.rotation = qY * qX;
/*效果:順序1:物體會先面向右側(Y軸旋轉),然后向上翻轉(X軸旋轉)。順序2:物體會先向上翻轉(X軸旋轉),然后面向右側(Y軸旋轉)。
最終朝向完全不同(可通過運行代碼觀察)。
*/
2. 點積(相似度)

四元數的點乘(Quaternion.Dot(q1, q2))返回值的范圍是 [-1, 1],表示兩個旋轉的相似程度:

1:完全相同旋轉。
-1:互為反向旋轉。
0:旋轉方向正交(無關)。

?????????Dot(q_{1},q_{2}) = q_{1}.x \cdot q_{2}.x +q_{1}.y \cdot q_{2}.y +q_{1}.z \cdot q_{2}.z +q_{1}.w \cdot q_{2}.w?????????????????????????

?實際應用場景
(1) 判斷旋轉是否完成

Quaternion targetRotation = Quaternion.Euler(0, 90, 0);
float similarity = Quaternion.Dot(transform.rotation, targetRotation);if (similarity > 0.999f) {Debug.Log("旋轉完成!");
}

(2) 平滑過渡檢測 在插值旋轉時,若相似度接近1,可提前終止插值以優化性能:

Quaternion current = transform.rotation;
Quaternion target = Quaternion.Euler(0, 90, 0);
float t = Quaternion.Dot(current, target);if (t < 0.99f) {transform.rotation = Quaternion.Slerp(current, target, Time.deltaTime * speed);
}

(3) 反向旋轉檢測

Quaternion inverse = Quaternion.Inverse(currentRotation);
float similarity = Quaternion.Dot(currentRotation, inverse);if (similarity < -0.999f) {Debug.Log("當前旋轉與反向旋轉對齊");
}
操作數學本質Unity中的作用典型場景
乘法(×)旋轉疊加(順序敏感)組合多個旋轉,或轉換坐標系角色轉身+抬頭、動畫疊加
點乘(Dot)四維空間中的夾角余弦檢測旋轉相似度、判斷旋轉完成或反向插值優化、AI朝向檢測、反向動作觸發

綜合對比:

using UnityEngine;public class QuaternionOperationsDemo : MonoBehaviour
{void Start(){// 1. 驗證乘法順序Quaternion qY = Quaternion.Euler(0, 90, 0);Quaternion qX = Quaternion.Euler(90, 0, 0);Debug.Log("順序1 (qX*qY): " + (qX * qY).eulerAngles); // 輸出 (90, 90, 0)Debug.Log("順序2 (qY*qX): " + (qY * qX).eulerAngles); // 輸出 (90, 90, 270)// 2. 驗證點乘相似度Quaternion a = Quaternion.identity;Quaternion b = Quaternion.Euler(0, 90, 0);Quaternion c = Quaternion.Inverse(b);Debug.Log("a vs b: " + Quaternion.Dot(a, b)); // 約0.7(不相似)Debug.Log("b vs b: " + Quaternion.Dot(b, b)); // 1(完全一致)Debug.Log("b vs c: " + Quaternion.Dot(b, c)); // -1(完全反向)}
}

3. 逆運算

四元數的逆(Inverse)表示反向旋轉。

公式

????????????????????????????????????????????????????????????????????q^{-1} = (-\frac{x}{||q||},-\frac{y}{||q||},-\frac{z}{||q||},-\frac{w}{||q||},)

例如:

Quaternion inverse = Quaternion.Inverse(rotation);

???????????????? ? ? ?這里同上,不再贅述

六、總結

四元數?Quaternion?屬性與方法總結

屬性/方法參數返回值簡單示例
identityQuaterniontransform.rotation = Quaternion.identity;
eulerAnglesVector3(歐拉角)Vector3 angles = transform.rotation.eulerAngles;
AngleAxisfloat angle,?Vector3 axisQuaternionQuaternion q = Quaternion.AngleAxis(90, Vector3.up);
Eulerfloat x,?float y,?float z?或?Vector3 eulerQuaternionQuaternion q = Quaternion.Euler(0, 90, 0);
SlerpQuaternion a,?Quaternion b,?float tQuaternionQuaternion.Slerp(current, target, Time.deltaTime * speed);
LerpQuaternion a,?Quaternion b,?float tQuaternionQuaternion.Lerp(current, target, Time.deltaTime * speed);
InverseQuaternion rotationQuaternionQuaternion inverse = Quaternion.Inverse(transform.rotation);
LookRotationVector3 forward,?Vector3 upwards=Vector3.up(可選)QuaternionQuaternion q = Quaternion.LookRotation(target.position - transform.position);
operator *Quaternion a,?Quaternion b(或?Vector3?向量)Quaternion?或?Vector3Quaternion combined = q1 * q2;
Vector3 rotated = q * Vector3.forward;
DotQuaternion a,?Quaternion bfloat(相似度)float similarity = Quaternion.Dot(q1, q2);

詳細說明

1. 屬性
屬性說明
identity表示無旋轉的四元數,等同于?new Quaternion(0, 0, 0, 1)
eulerAngles將四元數轉換為歐拉角(單位為度),僅用于調試,不可直接修改。
2. 方法
方法說明
AngleAxis繞指定軸旋轉指定角度(單位為度)。
Euler將歐拉角轉換為四元數(單位為度)。
Slerp沿球面最短路徑插值,適合平滑旋轉(如攝像機跟隨)。
Lerp線性插值,速度更快但路徑可能非最短。
Inverse返回反向旋轉的四元數(等效于逆矩陣)。
LookRotation生成朝向指定方向的四元數,默認以?Vector3.up?為向上方向。
3. 運算符與靜態方法
操作說明
operator *組合兩個四元數的旋轉,或對向量應用旋轉(順序為從右到左)。
Dot計算兩個四元數的四維點積,用于判斷旋轉相似度(1為相同,-1為反向)。

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/906376.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/906376.shtml
英文地址,請注明出處:http://en.pswp.cn/news/906376.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

活體檢測接口全面評測:2025年活體檢測選擇指南

一、活體檢測&#xff1a;數字化時代的身份驗證基石 活體檢測是一種通過分析人體生物特征動態變化來驗證身份真實性的技術&#xff0c;其核心在于區分真實人體與偽造樣本&#xff08;如照片、視頻、3D 面具等&#xff09;。技術原理主要基于以下維度&#xff1a; 多模態數據采…

物聯網工程畢業設計課題實踐指南

1. 智能家居控制系統 1.1 基于ZigBee的智能家居控制 實踐過程 硬件選型主控:CC2530/CC2531傳感器:溫濕度、光照、人體紅外執行器:繼電器、電機、LED燈系統架構 A[傳感器層] --> B[ZigBee網絡] B --> C[網關] C --> D[云平臺] D --> E[手機APP] 開…

電網中竊電分析:概念、算法與應用

一、引言 在現代電力系統中&#xff0c;竊電行為是一個嚴重影響電網經濟運行和供電秩序的問題。竊電不僅導致供電企業的經濟損失&#xff0c;破壞了電力市場的公平性&#xff0c;還可能對電網的安全穩定運行構成威脅&#xff0c;甚至引發安全事故。隨著科技的不斷進步&#xff…

一洽小程序接入說明

接入說明 文檔以微信小程序作為示例介紹&#xff0c;其他小程序接入操作與此類似 1、添加校驗文件 開發者使用微信小程序提供的 webview 組件可以實現打開一洽的H5對話 小程序的“域名配置”中添加一洽的對話域名地址&#xff0c;需要獲取校驗文件提供給一洽放在域名根目錄下…

【數據結構 -- AVL樹】用golang實現AVL樹

目錄 引言定義旋轉方式LL型RR型LR型RL型 實現結構獲取結點高度平衡因子更新高度左旋右旋插入結點中序遍歷 引言 AVL樹&#xff0c;基于二叉搜索樹通過平衡得到 前面我們知道&#xff0c;通過&#x1f517;二叉搜索樹可以便捷快速地查找到數據&#xff0c;但是當序列有序時&am…

PyTorch圖像識別模型和圖像分割模型體驗

文章目錄 倉庫地址練習&#xff1a;圖像自動識別模型數據集說明模型訓練和保存導入數據集搭建神經網絡訓練和保存實現 模型測試測試代碼測試結果 練習&#xff1a;圖像自動分割模型模型訓練和保存加載數據集搭建神經網絡訓練和保存 模型測試測試代碼測試效果 倉庫地址 圖像識別…

威綸通觸摸屏IP地址設定步驟及程序下載指南

在使用威綸通觸摸屏時&#xff0c;正確設定IP地址以及完成程序下載是確保其正常運行和實現功能的關鍵步驟。本文將詳細介紹威綸通觸摸屏IP地址設定步驟及程序下載的方法。 一、IP地址設定步驟 &#xff08;一&#xff09;前期準備 確保威綸通觸摸屏已經通電并啟動&#xff0…

一文讀懂|大模型智能體互操作協議:MCP/ACP/A2A/ANP

導讀 隨著推理大模型的出現&#xff08;deepseek&#xff0c;Qwen3等&#xff09;&#xff0c;進一步地推進了大模型的智能體系統發展。然而&#xff0c;如何使智能體更好的調用外部工具&#xff0c;智能體與智能體之間如何有機地協作&#xff0c;仍然沒有一個完美的答案。這篇…

前端下載ZIP包方法總結

在前端實現下載 ZIP 包到本地&#xff0c;通常有以下幾種方法&#xff0c;具體取決于 ZIP 包的來源&#xff08;靜態文件、后端生成、前端動態生成等&#xff09;&#xff1a; 方法 1&#xff1a;直接下載靜態文件&#xff08;最簡單&#xff09; 如果 ZIP 包是服務器上的靜態…

簡單使用Slidev和PPTist

簡單使用Slidev和PPTist 1 簡介 前端PPT制作有很多優秀的工具包&#xff0c;例如&#xff1a;Slidev、revealjs、PPTist等&#xff0c;Slidev對Markdown格式支持較好&#xff0c;適合與大模型結合使用&#xff0c;選喲二次封裝&#xff1b;revealjs適合做數據切換&#xff0c…

數據挖掘:從數據堆里“淘金”,你的數據價值被挖掘了嗎?

數據挖掘&#xff1a;從數據堆里“淘金”&#xff0c;你的數據價值被挖掘了嗎&#xff1f; 在這個數據爆炸的時代&#xff0c;我們每天都在產生海量信息&#xff1a;社交媒體上的點贊、網購時的瀏覽記錄&#xff0c;甚至是健身手環記錄下的步數。這些數據本身可能看似雜亂無章…

程序運行報錯分析文檔

zryhuawei:~/src/modules/Connect$ ./newbuild/OpConnectAidTool \WARNING: MYSQL_OPT_RECONNECT is deprecated and will be removed in a future version. replace into process_tracking (step_id,date,status,context_data,start_time,end_time,error_log) values(?,?,?…

基于flask+vue的電影可視化與智能推薦系統

基于flaskvue爬蟲的電影數據的智能推薦與可視化系統&#xff0c;能展示電影評分、評論情感分析等直觀的數據可視化圖表&#xff0c;還能通過協同過濾算法為用戶提供個性化電影推薦&#xff0c;幫助用戶發現更多感興趣的電影作品&#xff0c;具體界面如圖所示。 本系統主要技術架…

BYUCTF 2025

幾周沒會的比賽了&#xff0c;都是一題游。這周的BYU還不錯&#xff0c;難度適中&#xff0c;只是時間有點短。周末時間不夠。 Crypto Many Primes from Crypto.Util.number import bytes_to_long, getPrime import randomflag open("flag.txt").read().encode()…

鏈表的面試題8之環形鏈表

許久不見&#xff0c;那么這是最后倒數第三題了&#xff0c;這道題我們來看一下環形鏈表。 老規矩貼鏈接&#xff1a;141. 環形鏈表 - 力扣&#xff08;LeetCode&#xff09; 目錄 倒數第k個元素 獲取中間元素的問題。 雙指針 來&#xff0c;大致看一下題目&#xff0c;這…

在 JavaScript 中正確使用 Elasticsearch,第二部分

作者&#xff1a;來自 Elastic Jeffrey Rengifo 回顧生產環境中的最佳實踐&#xff0c;并講解如何在無服務器環境中運行 Elasticsearch Node.js 客戶端。 想獲得 Elastic 認證&#xff1f;查看下一期 Elasticsearch Engineer 培訓的時間&#xff01; Elasticsearch 擁有大量新…

2025年網站安全防御全解析:應對DDoS與CC攻擊的智能策略

2025年&#xff0c;隨著AI技術與物聯網設備的深度融合&#xff0c;DDoS與CC攻擊的規模與復雜度持續升級。攻擊者不僅利用T級流量洪泛沖擊帶寬&#xff0c;還通過生成式AI偽造用戶行為&#xff0c;繞過傳統防御規則。如何在保障業務高可用的同時抵御混合型攻擊&#xff1f;本文將…

window 安裝 wsl + cuda + Docker

WSL 部分參考這里安裝&#xff1a; Windows安裝WSL2 Ubuntu環境 - 知乎 如果出現錯誤&#xff1a; WslRegisterDistribution failed with error: 0x800701bc 需要運行&#xff1a;https://crayon-shin-chan.blog.csdn.net/article/details/122994190 wsl --update wsl --shu…

《MambaLLIE:基于隱式Retinex感知的低光照增強框架與全局-局部狀態空間建模》學習筆記

Paper:2405.16105 Github:GitHub - wengjiangwei/MambaLLIE 目錄 摘要 一、介紹 二、相關工作 2.1 低光圖像增強 2.2 視覺空間狀態模型 三、方法 3.1 預備知識 3.2 整體流程 3.3 全局優先-局部次之狀態空間塊 四、實驗 4.1 基準數據集與實施細節 4.2 對比實驗 4…

微信小程序:封裝request請求、解決請求路徑問題

一、創建文件 1、創建請求文件 創建工具類文件request.js,目的是用于發送請求 二、js接口封裝 1、寫入接口路徑 創建一個變量BASE_URL專門存儲api請求地址 2、獲取全局的token變量 從緩存中取出token的數據 3、執行請求 (1)方法中接收傳遞的參數 function request(url,…