從零開始圖形學(xué) | Matrix的線性變換和位移變換

在圖形學(xué)中矩陣統(tǒng)一以列矩陣的形式呈現(xiàn)
比如一個單列矩陣

A1=\left[ \begin{matrix} a1\\ a2\\ a3 \end{matrix} \right]
3*3矩陣
A3=\left[ \begin{matrix} a1&b1&c1\\ a2&b2&c2\\ a3&b3&c3 \end{matrix} \right]
在此之前補(bǔ)一個Markdown如何寫矩陣的內(nèi)容,感謝原貼分享!
https://blog.csdn.net/qq_38228254/article/details/79469727

圖片和內(nèi)容均來自GAMES101,萬分感謝大神的分享! http://games-cn.org/


進(jìn)入正題

線性變換包含我們常說的【縮放】【斜切】【旋轉(zhuǎn)】。

PS:這里我們以2D圖像為例

縮放矩陣

系數(shù)為0.5的縮放矩陣

等比即為原坐標(biāo)乘以比例系數(shù)

等比縮放的矩陣形式為

\left[ \begin{matrix} x' \\ y' \end{matrix} \right] = \left[ \begin{matrix} s&0\\ 0&s \end{matrix} \right] \left[ \begin{matrix} x\\ y \end{matrix} \right] = \left[ \begin{matrix} s*x + 0*y\\ 0*x + s*y \end{matrix} \right] \ = \left[ \begin{matrix} sx \\ sy \end{matrix} \right] \
從上可以看出,不等比縮放也同樣適用以上矩陣變換。

不等比矩陣對應(yīng)的兩個s系數(shù)不同

另,鏡像矩陣其實是縮放矩陣的一種特殊形式。
鏡像矩陣是系數(shù)為-1的縮放矩陣

斜切矩陣

理解斜切矩陣

簡單的理解,上圖中的斜切矩陣,在y方向上沒有變動,所以y' = y,在x方向上,所有的數(shù)值都向正方向移動了a,所以 x' = x + ax(注意這里a是倍數(shù)?。?/p>

旋轉(zhuǎn)矩陣

需要注意的是,旋轉(zhuǎn)矩陣通常默認(rèn)都是以坐標(biāo)原點(diǎn)作為pivot,旋轉(zhuǎn)方向為逆時針(CCW)。

旋轉(zhuǎn)矩陣的簡單推導(dǎo)驗證


旋轉(zhuǎn)矩陣的工作原理

取方形右下角{1, 0},旋轉(zhuǎn)后坐標(biāo)為{cosθ, sinθ},得出矩陣中 A = cosθ,C = sinθ;
相應(yīng)的,取左上角{0, 1},旋轉(zhuǎn)后的坐標(biāo)為(-sinθ, cosθ),得出矩陣中 B = -sinθ,D = cosθ。

二維旋轉(zhuǎn)矩陣

到這里其實已經(jīng)發(fā)現(xiàn)了線性變換的共性,即[目標(biāo)坐標(biāo)] = [矩陣]*[當(dāng)前坐標(biāo)]


線性變換公式

以上都是解決圍繞原點(diǎn)的問題,假如要實現(xiàn)如下的位移變換呢?

在 x 和 y 方向上位移t

此時回顧一下線性變換矩陣
\left[ \begin{matrix} x' \\ y' \end{matrix} \right] = \left[ \begin{matrix} a&b\\ c&d \end{matrix} \right] \left[ \begin{matrix} x\\ y \end{matrix} \right] = \left[ \begin{matrix} a*x + b*y\\ c*x + d*y \end{matrix} \right] \
會發(fā)現(xiàn)無論在任何情況下,都無法得到以上位移變換,也就是說,位移變換并不是線性變換!
位移變換是線性變換和位移向量共同作用的結(jié)果

那么有沒有辦法依然能夠通過 [單一矩陣]*[坐標(biāo)] 的形式來同時描述位移變換呢?有!這里我們要引入齊次坐標(biāo)。

齊次坐標(biāo) w

齊次坐標(biāo)的目的主要是合并矩陣運(yùn)算中的乘法和加法,表示為p' =M*p的形式。即它提供了用矩陣運(yùn)算把二維、三維甚至高維空間中的一個點(diǎn)集從一個坐標(biāo)系變換到另一個坐標(biāo)系的有效方法。
結(jié)合之前的案例,相當(dāng)于在原本2*2的矩陣上再增加一個維度變?yōu)?*3,返回結(jié)果如下


返回結(jié)果正是想要的位移變換

這時候考慮到向量的平移是不會變的,所以點(diǎn)的平移和向量的平移要區(qū)別對待,即



簡單理解,當(dāng)齊次坐標(biāo)補(bǔ)位值為1,則為向量,0則為點(diǎn)。
含有齊次坐標(biāo)的運(yùn)算法則

如果出現(xiàn)兩個點(diǎn)相加為2,則/2進(jìn)行歸一化處理,返回值為笛卡爾坐標(biāo)系中的中點(diǎn)坐標(biāo)。

那么,我們常規(guī)意義上的仿射變換就可以統(tǒng)一用如下矩陣來表示:


仿射變換轉(zhuǎn)變?yōu)榈刃У凝R次坐標(biāo)矩陣

所以,這里就可以解釋為什么要用4*4的矩陣來描述三維空間內(nèi)的轉(zhuǎn)換了。

如何解讀矩陣?
二維矩陣增加齊次坐標(biāo)后的解讀
逆變換
逆變換工作原理

簡單的理解,逆變換就像是逆向動力學(xué),而求逆矩陣的方法也很簡單,矩陣和逆矩陣相乘結(jié)果為單位矩陣。

M*M-1=\left[ \begin{matrix} 1&0&0\\ 0&1&0\\ 0&0&1 \end{matrix} \right]

矩陣變換次序很重要?。?!

先平移后旋轉(zhuǎn)VS先旋轉(zhuǎn)后平移

由于旋轉(zhuǎn)矩陣始終是以原點(diǎn)為軸心,先平移后旋轉(zhuǎn)會出現(xiàn)不合理的位移,所以矩陣一定是先旋轉(zhuǎn),后平移。



另外,由于行列式特殊的計算方式,矩陣相乘是不滿足交換律的。但是!多矩陣相乘可以添加在左側(cè),如下

多矩陣相乘

從這個角度看,矩陣的結(jié)合律其實就相當(dāng)于左乘,復(fù)雜的矩陣變換就可以變成 矩陣變換互相作用*坐標(biāo)

矩陣結(jié)合率

一個思考

如何讓一個物體圍繞一個特定的點(diǎn)來旋轉(zhuǎn)??

圍繞特定點(diǎn)的矩陣旋轉(zhuǎn)原理

核心是要拆分運(yùn)動,首先使用位移矩陣挪到原點(diǎn),然后作用旋轉(zhuǎn)矩陣,最后再用反向位移矩陣恢復(fù)坐標(biāo)c,完成!
整個過程中的核心是對旋轉(zhuǎn)點(diǎn)c的定義。

相應(yīng)的,在三維坐標(biāo)中添加齊次坐標(biāo)后就是我們常說的4*4矩陣了,作用方式同上述二維空間變換。


三維空間中的4*4矩陣

一個思考!

了解到旋轉(zhuǎn)矩陣的使用方法后,此時如果有圖像逆時針旋轉(zhuǎn)θ角,則為
Rθ=\left( \begin{matrix} cosθ&-sinθ\\ sinθ&cosθ \end{matrix} \right)

那么旋轉(zhuǎn)-θ呢?(畫個圖看一下就能推出來了)
R=\left( \begin{matrix} cosθ&sinθ\\ -sinθ&cosθ \end{matrix} \right)

此時觀察兩個矩陣之間的關(guān)系,得出旋轉(zhuǎn)-θ的矩陣就是旋轉(zhuǎn)θ的轉(zhuǎn)置(行列對換)
R = RθT

另,根據(jù)定義,旋轉(zhuǎn)-θ的和旋轉(zhuǎn)θ應(yīng)該是互逆的,也就是
R = Rθ-1
所以得出最終結(jié)論====>

旋轉(zhuǎn)矩陣的逆 = 旋轉(zhuǎn)矩陣的轉(zhuǎn)置

Rθ-1 = RθT

也就是常說的正交矩陣。

三維呢?

類似的,在三維狀態(tài)下的矩陣,也需要齊次坐標(biāo)

三維中的齊次坐標(biāo)

三維中的縮放和平移

然而在旋轉(zhuǎn)矩陣中,情況有所不同
Y軸旋轉(zhuǎn)有所不同

為什么Ry和其他兩個軸不一致?
因為在三維狀態(tài)下,按照右手螺旋定則,如果是X*Z,得到的是Y方向的反方向,所以需要取-θ。
剛剛在二維空間中已經(jīng)論證過了旋轉(zhuǎn)θ和-θ的轉(zhuǎn)置和互逆關(guān)系,所以Y軸旋轉(zhuǎn)需要求轉(zhuǎn)置矩陣。

傳說中的歐拉角旋轉(zhuǎn)

復(fù)雜旋轉(zhuǎn)的合成

然而,有一種特殊情況,是歐拉角的bug——Gimbal Lock(萬向節(jié)死鎖)。
簡單的理解,因為旋轉(zhuǎn)矩陣的計算方式是有次序的(通常是以zyx為順序而不是xyz),動態(tài)歐拉角會出現(xiàn)兩個旋轉(zhuǎn)軸在某個過程中重合的情況,此時就會有一個維度的消失。
在這個鏈接中有詳細(xì)且直觀的解釋https://v.youku.com/v_show/id_XNzkyOTIyMTI=.html
另,一種旋轉(zhuǎn)狀態(tài)可能對應(yīng)多種歐拉角甚至無數(shù)種。
雖然起點(diǎn)和結(jié)果相同,但是中間的插值計算導(dǎo)致了萬向節(jié)鎖死就會出現(xiàn)尷尬時刻

所以也就有了羅德里格斯旋轉(zhuǎn)公式


image.png

以及

大惡魔——“四元數(shù)”Quaternion!

關(guān)于四元數(shù)需要太多的先導(dǎo)學(xué)習(xí),需要一整節(jié)來整理。
先來一個網(wǎng)站https://eater.net/quaternions
非常交互式的理解四元數(shù),非常非常推薦閱讀觀看!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容