1. 程式人生 > >【Unity技巧】四元數(Quaternion)和旋轉

【Unity技巧】四元數(Quaternion)和旋轉

四元數介紹

旋轉,應該是三種座標變換——縮放、旋轉和平移,中最複雜的一種了。大家應該都聽過,有一種旋轉的表示方法叫四元數。按照我們的習慣,我們更加熟悉的是另外兩種旋轉的表示方法——矩陣旋轉和尤拉旋轉。矩陣旋轉使用了一個4*4大小的矩陣來表示繞任意軸旋轉的變換矩陣,而尤拉選擇則是按照一定的座標軸順序(例如先x、再y、最後z)、每個軸旋轉一定角度來變換座標或向量,它實際上是一系列座標軸旋轉的組合。

那麼,四元數又是什麼呢?簡單來說,四元數本質上是一種高階複數(聽不懂了吧。。。),是一個四維空間,相對於複數的二維空間。我們高中的時候應該都學過複數,一個複數由實部和虛部組成,即x = a + bi,i是虛數單位,如果你還記得的話應該知道i^2 = -1。而四元數其實和我們學到的這種是類似的,不同的是,它的虛部包含了三個虛數單位,i、j、k,即一個四元數可以表示為x = a + bi + cj + dk。那麼,它和旋轉為什麼會有關係呢?

在Unity裡,tranform元件有一個變數名為rotation,它的型別就是四元數。很多初學者會直接取rotation的x、y、z,認為它們分別對應了Transform面板裡R的各個分量。當然很快我們就會發現這是完全不對的。實際上,四元數的x、y、z和R的那三個值從直觀上來講沒什麼關係,當然會存在一個表示式可以轉換,在後面會講。

大家應該和我一樣都有很多疑問,既然已經存在了這兩種旋轉表示方式,為什麼還要使用四元數這種聽起來很難懂的東西呢?我們先要了解這三種旋轉方式的優缺點:

  • 矩陣旋轉
    • 優點:
      • 旋轉軸可以是任意向量;
    • 缺點:
      • 旋轉其實只需要知道一個向量+一個角度,一共4個值的資訊,但矩陣法卻使用了16個元素;
      • 而且在做乘法操作時也會增加計算量,造成了空間和時間上的一些浪費;

  • 尤拉旋轉
    • 優點:
      • 很容易理解,形象直觀;
      • 表示更方便,只需要3個值(分別對應x、y、z軸的旋轉角度);但按我的理解,它還是轉換到了3個3*3的矩陣做變換,效率不如四元數;
    • 缺點:
      • 之前提到過這種方法是要按照一個固定的座標軸的順序旋轉的,因此不同的順序會造成不同的結果;
      • 會造成萬向節鎖(Gimbal Lock)的現象。這種現象的發生就是由於上述固定座標軸旋轉順序造成的。理論上,尤拉旋轉可以靠這種順序讓一個物體指到任何一個想要的方向,但如果在旋轉中不幸讓某些座標軸重合了就會發生萬向節鎖,這時就會丟失一個方向上的旋轉能力,也就是說在這種狀態下我們無論怎麼旋轉(當然還是要原先的順序)都不可能得到某些想要的旋轉效果,除非我們打破原先的旋轉順序或者同時旋轉3個座標軸。這裡有個
        視訊
        可以直觀的理解下;
      • 由於萬向節鎖的存在,尤拉旋轉無法實現球面平滑插值;

  • 四元數旋轉
    • 優點:
      • 可以避免萬向節鎖現象;
      • 只需要一個4維的四元數就可以執行繞任意過原點的向量的旋轉,方便快捷,在某些實現下比旋轉矩陣效率更高;
      • 可以提供平滑插值;
    • 缺點:
      • 比尤拉旋轉稍微複雜了一點點,因為多了一個維度;
      • 理解更困難,不直觀;

四元數和尤拉角

基礎知識

前面說過,一個四元數可以表示為q = w + xi + yj + zk,現在就來回答這樣一個簡單的式子是怎麼和三維旋轉結合在一起的。為了方便,我們下面使用q = ((x, y, z),w) = (v, w),其中v是向量,w是實數,這樣的式子來表示一個四元數。我們先來看問題的答案。我們可以使用一個四元數q=((x,y,z)sinθ2, cosθ2) 來執行一個旋轉。具體來說,如果我們想要把空間的一個點P繞著單位向量軸u = (x, y, z)表示的旋轉軸旋轉θ角度,我們首先把點P擴充套件到四元數空間,即四元數p = (P, 0)。那麼,旋轉後新的點對應的四元數(當然這個計算而得的四元數的實部為0,虛部係數就是新的座標)為:

p=qpq1
其中,q=(cosθ2, (x,y,z)sinθ2)q1=qN(q),由於u是單位向量,因此
N
(q)
=1,即q1=q。右邊表示式包含了四元數乘法。相關的定義如下:
  • 四元數乘法:q1q2=(v1×v2+w1v2+w2v1,w1w2v1v2)
  • 共軛四元數:

    相關推薦

    Unity技巧Quaternion旋轉

    四元數介紹旋轉,應該是三種座標變換——縮放、旋轉和平移,中最複雜的一種了。大家應該都聽過,有一種旋轉的表示方法叫四元數。按照我們的習慣,我們更加熟悉的是另外兩種旋轉的表示方法——矩陣旋轉和尤拉旋轉。矩陣

    洛谷P1012 拼貪心

    題目連結 題目描述 設有 n 個正整數 (n≤20)將它們聯接成一排,組成一個最大的多位整數。 例如: n=3 時, 3 個整數 13 , 312 , 343 聯接成的最大整數為: 34331213 又如: n=4 時, 4 個整數 7 , 13 , 44 , 246

    Introduction to 3D Game Programming with DirectX 12 學習筆記之 --- 第二十二章:QUATERNIONS

    directx height ebe beginning ++ tip osi 通過 假設 原文:Introduction to 3D Game Programming with DirectX 12 學習筆記之 --- 第二十二章:四元數(QUATERNIONS)

    機器學習簡單理解精確度precision準確率accuracy的區別

        不少人對分類指標中的Precision和Accuracy區分不開,在其他部落格中也有很多相關介紹,但總體不夠簡明易懂。     筆者在查閱了若干資料後,總結如下:     Precis

    Unity技巧調整畫質貼圖質量

    寫在前面 當我們在Unity中,使用圖片進行2D顯示時,會發現顯示出來的畫面有明顯的模糊或者鋸齒,但是美術給的原圖卻十分清晰。 要改善這一狀況實際上很簡單。 造成這樣的原因,是Unity在匯入圖片

    Unity技巧Unity中的優化技術

    移動設備 完整 物體 動態 多少 each blank screen text 寫在前面 這一篇是在Digital Tutors的一個系列教程的基礎上總結擴展而得的~Digital Tutors是一個非常棒的教程網站,包含了多媒體領域很多方面的資料,非常酷!除此之外,還

    慣性導航之認識

    之前說到,使用尤拉角積分和方向餘弦積分求得角度並不合適,而比較合適的是四元數。 在討論「四元數」之前,我們來想想對三維直角座標而言,在物體旋轉會有何影響,可以擴充三維直角座標系統的旋轉為三角度系統(Three-angle system),在Game Pr

    Unity 3D 5.6版本使用3點選物體彈出視窗顯示狀態

    emmm直接看程式碼 using System.Collections; using System.Collections.Generic; using UnityEngine; public class ShowWindow : MonoBehavio

    Python學習筆記、對映Mapping

    • 通過名字來引用值得資料結構稱為對映字典(Dict)•   字典是鍵值對(key-value pair)的無序可變集合。(1)字典的操作①字典的建立• 字典中的每個元素包含兩部分:鍵和值。• 鍵和值用冒號分隔,元素間用逗號分隔,所有元素放在一對大括號中。d = {key1

    Unity技巧統一管理回撥函式——觀察者模式

    using UnityEngine; using System.Collections; using System.Collections.Generic; public class TimerController : MonoBehaviour { public delegate void OnC

    Cloud FoundryCould Foundry學習——Could Foundry淺談

    art lock mod out isp ted 組成 .com pop 在閱讀的過程中有不論什麽問題。歡迎一起交流 郵箱:[email protected]/* */ QQ:1494713801 Cloud Foundry是VMware

    7.13單例模式Singleton的用法用處以及破解單例

    vol 創建者模式 code private let .get span test loaded 1):用處   是一種創建者模式,只生成一個實例對象,具有全局唯一性,當一個對象的產生需要比較多的資源時, 如讀取配置(如數據庫連接池、Spring中, 一個Compone

    C#圖解PictureBox.SizeMode 屬性

    img attach mage 圖解 auto deb ict cmm src PictureBoxSizeMode.Normal: 默認情況下,在 Normal 模式中,Image 置於 PictureBox 的左上角,凡是因過大而不適合 PictureBox 的任何

    洛谷P2434 [SDOI2005]區間暴力

    輸入輸出 pre spa scan break 輸入格式 我們 return 描述 題目描述 現給定n個閉區間[ai, bi],1<=i<=n。這些區間的並可以表示為一些不相交的閉區間的並。你的任務就是在這些表示方式中找出包含最少區間的方案。你的輸出應該按照區

    洛谷P2725 郵票 Stampsdp

    adg symbol 能夠 循環 tro 總數 技術分享 std 答案 題目背景 給一組 N 枚郵票的面值集合(如,{1 分,3 分})和一個上限 K —— 表示信封上能夠貼 K 張郵票。計算從 1 到 M 的最大連續可貼出的郵資。 題目描述

    分治法線性時間選擇

    算法思路 ont 位置 劃分 得到 子數組 als lena part 轉自:http://blog.csdn.net/liufeng_king/article/details/8480430 線性時間選擇問題:給定線性序集中n個元素和一個整數k,1≤k≤n,要求找出這n

    筆記篇斜率優化dp USACO08MAR土地購(征)買(用)Land Acquisition

    body 遞增 std char log lin 關鍵字排序 斜率優化 getchar 好好的題目連個名字都不統一.. 看到這種最大最小的就先排個序嘛= =以x為第一關鍵字, y為第二關鍵字排序. 然後有一些\(x_i<=x_{i+1},且y_i<=y_{i+

    筆記篇斜率優化dp HNOI2008玩具裝箱

    公式 現在 getchar() 就是 clu cst 差距 直接 source 斜率優化dp 本來想直接肝這玩意的結果還是被忽悠著做了兩道數論現在整天渾渾噩噩無心學習甚至都不是太想頹廢是不是藥丸的表現各位要知道我就是故意要打刪除線並不是因為排版錯亂反正就是一個del標簽嘛

    筆記篇斜率優化dp SDOI2016征途

    不能 最小化 征途 這樣的 string cpp mar logs -s =======傳=送=門======= 搜題目名會搜出很多奇怪的東西... 這個題目似乎有點毒? 比如在bzoj和loj上可以1A的代碼上會在luogu TLE 2個點, 在cogs TLE 10個

    筆記篇斜率優化dp APIO2010特別行動隊

    tex http span type 2-2 參加 math 就是 裏的 旁聽了一波給舒老師和學弟的pkuwc面試講座... 這裏有一段隱身的吐槽, 想看的請自己想辦法觀看. 不想看的跳過這一段看似空白的東西就好了... 剛開始ATP學姐給我們講了自己面試的時候的事情.