計算機(jī)圖形學(xué):變換矩陣
大家好,我是前端西瓜哥。今天我們來學(xué)變換矩陣。
線性變換
矩陣乘法是來自線性代數(shù)的內(nèi)容。
首先我們有一個二維的向量 (x, y),它在線性代數(shù)中,我們會這么表示:
向量在幾何中會用一條起始于原點(diǎn)的箭頭表示。
向量我們也常??醋饕粋€點(diǎn)。因?yàn)楫?dāng)有大量向量要繪制時,箭頭就會非常的多,會讓畫面非常混亂,所以要簡化為點(diǎn)。
向量加法:對應(yīng)位置進(jìn)行相加即可,在幾何中可以將多個向量頭尾相連,最終的路徑就是加法的結(jié)果:
數(shù)乘:或者叫標(biāo)量乘法,指的是將向量和一個常量數(shù)字進(jìn)行相乘,也是對應(yīng)位置相乘,在幾何中表現(xiàn)為對向量縮放:
有了上面兩個概念,我們得到對于一個二維向量,它是 x 軸上和 y 軸上的單位向量(一種 基向量)進(jìn)行縮放后組合而成:
然后就是我們主角 線性變換了。
線性變換的 “變換”,指的是 “函數(shù)”,它接受一個向量,然后返回一個向量。在幾何中,它表示了一個向量是怎么從原來的指向變換(縮放旋轉(zhuǎn)等過程)成另一個指向。
線性變換的 “線性”,指的是這個變換是符合一些特性的,首先是直線變換后還是直線,然后就是原點(diǎn)保持在原來的位置。
線性變換,一種理解為,矩形的每列改變了對應(yīng)基向量的值。
比如上面的公式,我們的 (x, y) 向量原來是基于 i 向量 (1, 0) 和 j 向量 (0, 1) 進(jìn)行數(shù)乘得到的。
但通過一個矩陣,我們的 i 和 j 分別變成了(a, c) 和 (b, d),即標(biāo)準(zhǔn)換了,基于這個新標(biāo)準(zhǔn)得到的新的值就是線性變換的輸出向量。
下面我們看一些常見的變換矩陣。
縮放
縮放,就是將一個向量(或者點(diǎn))的 x 和 y 各自進(jìn)行指定比例的縮放。
假設(shè) x 方向縮放比例為 sx,y 方向縮放比例為 sy。簡單的算法就是:
二維 2x2 縮放矩陣為:
二維矩陣運(yùn)算過程為:
實(shí)際上我們會使用三維縮放矩陣,原因會在下面平移中講解。
三維縮放矩陣為:
下邊和右邊各加上 0 0 1 即可。
平移
平移,就是將一個向量(或者點(diǎn))的 x 和 y 各自移動一段距離。
假設(shè) x 方向移動 dx 距離,y 方向移動 dy 距離。
直接用幾何的描述:
我們無法用一個二維矩陣來表示平移變換,為此我們需要升維,升到三維,通過額外的一個 z 軸的基向量的斜切來模擬二維中的平移。
輸入向量也需要升維,加多一個值為 1 的第三維度:
三維平移矩陣為:
運(yùn)算過程:
為了減少計算量,我們會使用 復(fù)合矩陣,就是將多個變換矩陣通過結(jié)合律計算出來的矩陣。
它是多種矩陣的組合體,但相比對一個向量一個個進(jìn)行矩陣乘法,符合矩陣能一次計算出來。因?yàn)槠揭频奶厥庑裕晕覀兺ǔ2粫褂?2x2 矩陣來表示一個變換矩陣,而是用 3x3 矩陣,來和平移矩陣做兼容。
旋轉(zhuǎn)
點(diǎn)沿原點(diǎn)逆時針旋轉(zhuǎn)指定角度,得到新的坐標(biāo)點(diǎn),有以下公式:
三維旋轉(zhuǎn)矩陣:
逆時針旋轉(zhuǎn) 90度,可以看作是給基變量做旋轉(zhuǎn):
斜切
斜切,其實(shí)就是固定一個基向量不變,改變另一條基向量。斜切是有方向的。
水平斜切:
或垂直斜切:
水平斜切動圖:
代碼實(shí)現(xiàn)
通常我們會用升維的 3x3 矩陣,來表示一個變換矩形,因?yàn)樽詈笠恍杏肋h(yuǎn)都是 [0, 0, 1],所以我們的函數(shù)只需要傳矩陣的前兩行,共 6 個值。比如 Canvas 的 ctx.transform 也是只接受 6 個值。
結(jié)尾
本文簡單講了一下變換矩陣。