歡迎光臨ELBE網(wǎng)站!
您的位置: ELBE > 行業(yè)資訊 > 四元數(shù)應(yīng)用——轉(zhuǎn)矩陣、Slerp插值與萬向節(jié)
網(wǎng)站頭像

文章分類

Article classification
聯(lián)系我們

ELBE

電話:021-58780503 微信:18017854633 郵箱:sales_fullyear@126.com 地址:上海市浦東新區(qū)城南路168弄3號(hào)峰匯商務(wù)廣場B座911室
四元數(shù)應(yīng)用——轉(zhuǎn)矩陣、Slerp插值與萬向節(jié)
時(shí)間:2022-12-16 查看:34 作者:小葉

四元數(shù)系列:

四元數(shù)-基本概念

四元數(shù)-旋轉(zhuǎn)

四元數(shù)應(yīng)用-轉(zhuǎn)矩陣Slerp插值與萬向節(jié)

四元數(shù)應(yīng)用-旋轉(zhuǎn)混合順序無關(guān)

—————————————————————————————————————————

今天,我們來談?wù)勔恍╆P(guān)于四元數(shù)的例子。與前兩篇文章相比,它們可能有點(diǎn)分散,這是對(duì)前兩章的補(bǔ)充說明。具體來說,我們將討論三個(gè)問題。第一個(gè)是四元數(shù)和矩陣的轉(zhuǎn)換,第二個(gè)是四元數(shù)的插入值。最后,我們來談?wù)勅f向節(jié)鎖的問題。話不多說,開始談話。

1.四元數(shù)矩陣形式

目前,大多數(shù)底層的圖形API,空間坐標(biāo)的轉(zhuǎn)換仍然基于矩陣。因此,當(dāng)我們使用四元數(shù)來操作旋轉(zhuǎn)時(shí),最終傳輸給頂點(diǎn)著色器的數(shù)據(jù)應(yīng)以矩陣的形式進(jìn)行。然而,從應(yīng)用層的角度來看,我們可以通過滿足以下公式來實(shí)現(xiàn)轉(zhuǎn)換。

我相信大多數(shù)人對(duì)背誦公式并不滿意。推導(dǎo)公式的主要方法有兩種。其中一個(gè)是從代數(shù)的角度解決問題。直率地說,這是一個(gè)硬算。我們?cè)谒脑獢?shù)和旋轉(zhuǎn)(2)中提到了一個(gè)公式:

我們可以找到三個(gè)矩陣,然后添加上述轉(zhuǎn)換公式。這里沒有推導(dǎo),感興趣的人可以自己計(jì)算。以下是一種更靈性的證明方法。當(dāng)給出以下兩個(gè)四元數(shù)時(shí):

如下圖所示:

可以說,兩個(gè)四元數(shù)相乘轉(zhuǎn)換為矩陣L右乘四元數(shù)q。發(fā)散思維,把這種行為寫成矩陣R左乘四元數(shù)q,具體形式如下圖所示:

最體看L和R括號(hào)中的四元下標(biāo)非常重要,因?yàn)樗脑环辖粨Q規(guī)律,括號(hào)中的下標(biāo)實(shí)際上是不同的我們必須注意這個(gè)地方?;A(chǔ)知識(shí)完成后,直接應(yīng)用于下面。根據(jù)旋轉(zhuǎn)公式和上述定義,我們很容易得到以下公式:

然后將L和R在上述矩陣中,我們可以得到:

證畢!

2.四元數(shù)的Slerp插值

事實(shí)上,插值問題一直是圖形學(xué)中的一個(gè)經(jīng)典問題。一般來說,線性插值可以滿足大多數(shù)情況,但對(duì)于旋轉(zhuǎn),線性插值肯定不好。讓我們下圖:

很明顯,左圖(線插)比右圖(球插)差。從動(dòng)畫的角度來看,為了保證每幀的旋轉(zhuǎn)均勻變化,線性插值得到的旋轉(zhuǎn)結(jié)果必須不均勻,主要考慮旋轉(zhuǎn)角度。然后我們從代數(shù)的角度來思考。如果兩個(gè)單位的四元數(shù)之間的插值,如左圖的線性插值,則得到的四元數(shù)不得為單位的四元數(shù)。我們希望旋轉(zhuǎn)插值不會(huì)改變長度,因此顯然右圖的球面(Slerp)插值更合理。

四元數(shù)球面插值證明很多,Wiki上面有非常詳細(xì)的證據(jù)和實(shí)現(xiàn)Code。事實(shí)上,主要思想是施密特正交。首先,根據(jù) 和 解算兩個(gè)正 交四元,然后通過加權(quán)計(jì)算最終 。下圖可以很好地解釋這件事。

下面主要討論的是這個(gè)問題。上圖給出了一種球面插值公式,暫時(shí)稱為加法形式。由于四元旋轉(zhuǎn)是相乘的,我們的上述公式也可以寫成:

鑒于刨根問底的精神,先說四元數(shù)的差異。(Difference),這更容易理解,類似于矩陣,A與B的差異可以理解為先旋轉(zhuǎn)A,然后旋轉(zhuǎn)B,得到A和B兩者之間的差值,表示為 。然后,如果我們?nèi)倍差或直接說差乘以t因子,我們將引用四元數(shù)和旋轉(zhuǎn)(1)中提到的四元數(shù)指數(shù)形式。對(duì)于 ,我們來看看 和 具體情況如下:

最后我們令 以及 ,根據(jù)以下公式重新審視球面插值:

可見,兩種表現(xiàn)形式可以相互轉(zhuǎn)化。

三、萬向節(jié)死鎖

事實(shí)上,這個(gè)問題不能算作四元的應(yīng)用。在萬向節(jié)鎖的早期階段,它被用來處理旋轉(zhuǎn)過程中機(jī)械臂缺乏自由度的問題。由于當(dāng)時(shí)機(jī)械臂的關(guān)節(jié)是單自由的,在模擬人體的一些球形關(guān)節(jié)(自由度為3的關(guān)節(jié))時(shí),將使用三組正交機(jī)械關(guān)節(jié)進(jìn)行模擬。

如圖所示,當(dāng)關(guān)節(jié)2旋轉(zhuǎn)90時(shí),機(jī)械關(guān)節(jié)1-3共同模擬手腕活動(dòng)°之后關(guān)節(jié)1和關(guān)節(jié)3會(huì)重疊,所以旋轉(zhuǎn)關(guān)節(jié)1和旋轉(zhuǎn)關(guān)節(jié)3只會(huì)沿著 旋轉(zhuǎn)軸,這就是萬向節(jié)鎖。值得一提的是,當(dāng)你旋轉(zhuǎn)關(guān)節(jié)1、關(guān)節(jié)2和關(guān)節(jié)3時(shí),當(dāng)你旋轉(zhuǎn)關(guān)節(jié)3時(shí),無論如何旋轉(zhuǎn)都不會(huì)影響關(guān)節(jié)2和關(guān)節(jié)1,所以只有關(guān)節(jié)2旋轉(zhuǎn)90°萬向節(jié)鎖會(huì)產(chǎn)生。

當(dāng)早期的計(jì)算機(jī)動(dòng)畫移動(dòng)機(jī)器人時(shí),最簡單的方法是直接模擬歐拉角的旋轉(zhuǎn)。這導(dǎo)致了通用鎖。那么如何理解計(jì)算機(jī)動(dòng)畫中的這個(gè)問題呢?畢竟,動(dòng)畫中沒有機(jī)械關(guān)節(jié)。

假設(shè)三個(gè)歐拉角的旋轉(zhuǎn)順序如下

當(dāng) 的時(shí)候, 和 它將重疊,如右圖,從而產(chǎn)生萬向節(jié)鎖。

因此,為了避免這個(gè)問題,圖形旋轉(zhuǎn)開始使用軸角,因?yàn)檩S角可以說三個(gè)歐拉角等同于繞特定軸旋轉(zhuǎn)的角度。OpenGL有個(gè)函數(shù)glRotate實(shí)現(xiàn)函數(shù)的方法是使用軸角。當(dāng)然,并不是說軸角沒有萬向鎖。當(dāng)三個(gè)正交軸角按一定順序旋轉(zhuǎn)時(shí),仍然會(huì)產(chǎn)生萬向鎖,但這種情況很難發(fā)生。

所以軸角解決了這個(gè)問題,為什么要用四元數(shù)?

4.總結(jié)四元數(shù)

最后點(diǎn)一個(gè)問題,呼應(yīng)前面的文章,具體說說四元數(shù)的好處:

解決萬向節(jié)鎖(Gimbal Lock)問題。(不要用四元數(shù)模擬歐拉角!)只需存儲(chǔ)4個(gè)浮點(diǎn),比矩陣輕。例如,矩陣至少需要9個(gè)float表示旋轉(zhuǎn)信息,即使加上旋轉(zhuǎn)縮放,也會(huì)比矩陣少存2-6個(gè)float,對(duì)于在PC游戲的開發(fā)可能并不明顯,畢竟,現(xiàn)在內(nèi)存很大,但在家用機(jī)器(尤其是上一代)中,內(nèi)存相對(duì)較緊是相當(dāng)有利的。無論是求逆、串聯(lián)等操作,四元數(shù)都比矩陣更高效。例如,逆轉(zhuǎn)相當(dāng)于逆轉(zhuǎn)。即使是正交矩陣,轉(zhuǎn)移的操作成本也遠(yuǎn)高于逆轉(zhuǎn)。此外,在大多數(shù)情況下,由于縮放,逆轉(zhuǎn)操作將更加復(fù)雜。然而,使用四元數(shù)需要考慮轉(zhuǎn)換四元數(shù)和矩陣的成本,但綜合考慮,四元數(shù)的運(yùn)行成本相對(duì)較低。

基本上四元數(shù)在我這里就結(jié)束了,以后會(huì)有人請(qǐng)人 @Obsver Anonym 請(qǐng)期待更新一篇具體應(yīng)用的文章!

繼續(xù)閱讀與本文標(biāo)簽相同的文章
cache
Processed in 0.023250 Second.