乘風破浪的WebGL系列-仿射變換數學基礎

希沃ENOW大前端前端

公司官網:CVTE(廣州視源股份)git

團隊:CVTE旗下將來教育希沃軟件平臺中心enow團隊github

本文做者:markdown

前言

向量的基本仿射變換分爲平移、縮放和旋轉。在學習如何使用 WebGL 繪製 3D 形體前,咱們須要學習如何對物體進行仿射變換,好比要看到 3D 物體的不一樣側面咱們須要學習如何對其進行旋轉(只看正面看不出立體效果),另外咱們要想添加多個方向或者位置不一樣的 3D 形體時,不須要重複計算每一個形體的頂點,而是能夠經過對同一形體進行各類各樣的仿射變換來實現。因此,讓咱們學習和回顧仿射變換的基礎數學知識——向量和矩陣吧。函數

本系列其它連接:oop

向量

向量是既有大小,又有方向的量,在物理和工程學中又稱爲矢量。與之對應的是標量,標量只有大小,沒有方向。如身高、體重等。在GLSL 着色器語言中咱們可使用 vec二、vec三、vec4 和 ivec二、ivec三、ivec4 等來表示不一樣維度、不一樣數據類型的向量,如 vec3(x, y, z) 表示數據類型爲 float 的三維向量。
post

向量與標量的運算

向量與標量不能相加減,但能夠相乘除。向量與向量進行相乘或者相除,須要將向量的每個元素都與該標量進行相應的運算。向量乘以標量 n 的意義是向量的長度縮放 n 倍。例如向量 3學習

向量的加減法

向量與向量的加減法能夠被定義爲是向量份量的相加或相減,即將一個向量中的每個份量加上或減去另外一個向量的對應份量。例如向量 加向量 爲: 優化

向量加法的幾何意義是,將兩個向量首尾順次相接,結果爲第一個向量的起點指向最後一個向量的終點。spa


向量減法的幾何意義是,將兩個向量平移至公共起點,以向量的兩條邊做平行四邊形,結果由減向量的終點指向被減向量的終點。


兩個向量相等須要知足大小相等和方向相同。

 和 獲得的向量是大小和方向相同的,所以能夠說向量加法知足交換律;而 和  獲得的向量是大小相同但方向相反,所以說向量減法不知足交換律。

向量的乘法

向量乘法有兩種,一種是點乘(Dot Product),一種是叉乘(Cross Product)

點乘

1.點乘的代數定義
設二維空間內有兩個向量,定義它們的點乘爲如下實數:



2.點乘的幾何定義
設二維空間內有兩個向量 表示向量的大小,二者間的夾角爲 θ,則點乘的幾何定義以下:



 乘以  在  上的投影份量

3.點乘的做用
點乘能夠用來計算兩個向量間的夾角。結合上面兩條公式,能夠推出 ,再利用反餘弦函數 便可得到夾角值。點乘在計算光照的時候很是有用,好比在聚光燈的效果計算中,能夠根據點乘來獲得光照效果,若是點乘越大,說明夾角越小,則物體離光照的軸線越近,光照越強。在 GLSL 中內置了點乘函數dot(v1, v2)

叉乘

1.叉乘的數學計算
和點乘不一樣的是,叉乘的結果不是標量,而是方向與相叉乘的兩個向量組成的平面垂直的向量。定義兩個三維向量  和 ,  的叉乘能夠表示爲以下的行列式:



其中,i、j、k 分別是 x、y、z 軸的單位向量。利用特定公式對其進行展開,以下:



2.叉乘的幾何定義
 和 的叉乘的幾何含義是,組成的平行四邊形的面積。


3.叉乘的做用
叉乘一樣能夠用來計算向量的夾角,結合上面兩條公式,能夠求出 ,再利用反正弦函數  便可獲取夾角值。叉積還能夠被運用在求解物體表面法向量。GLSL 中內置了叉乘函數 cross(v1, v2)

矩陣

矩陣是按照行列排列的一系列數值的集合,一個矩陣一般是由 mn 列組成,咱們稱之爲m x n 矩陣。在 GLSL 着色器語言中咱們可使用 mat二、mat三、mat2x三、mat3x4 等來表示不一樣行列數的矩陣,如 mat3 表示行列數爲 3x3 的矩陣。

矩陣的加減法

矩陣與標量的加減法,須要將標量值加或減到矩陣的每個元素上。


矩與矩陣的加減法能夠被定義爲是份量的相加,即將一個矩陣中的每個份量加上另外一個矩陣的對應份量。

矩陣相乘

矩陣與標量的乘法和矩陣與標量的加減法同樣,矩陣與標量之間的乘法也是矩陣的每個元素分別乘以該標量。

矩陣與矩陣相乘,須要知足左側矩陣的列數與右側矩陣的行數相等。結果矩陣的行數爲左側矩陣的行數,列數等於右側矩陣的列數。

其中,結果矩陣的第一行第一個值爲左邊第一行和右邊第一列的乘積,依此類推。

矩陣與仿射變換

仿射變換是指在幾何中,一個向量空間進行一次線性變換並接上一個平移,變換爲另外一個向量空間。仿射變換具備如下兩個特性:

  1. 仿射變換前是直線段的,仿射變換後依然是直線段
  2. 對兩條直線段 ab 應用一樣的仿射變換,變換先後線段長度比例保持不變


對於線性變換,指的是從一個向量空間 v 到另外一個向量空間 w 的映射且保持加法運算和數量乘法運算。線性變換除了具備仿射的那兩個特性外,還包括如下兩個特性:

  1. 線性變換不改變座標原點
  2. 線性變換能夠疊加,多個線性變換的疊加結果就是將線性變換的矩陣依次相乘,再與原始向量相乘


縮放和旋轉等變換都屬於線性變換,而由第一條特性能夠知道,平移不屬於線性變換。

瞭解了什麼是仿射變換後,讓咱們來看看仿射變換中經常使用的平移、縮放和旋轉是如何計算的吧。

平移

平移是在原始向量的基礎上加上另外一個向量從而得到一個在不一樣位置的新向量的過程,咱們可使用向量加法得出平移後的向量:

若是使用 3×3 的矩陣,咱們沒法定義一個三維的空間的平移矩陣,後面咱們會講到使用齊次座標定義平移矩陣。

縮放

對一個向量進行縮放就是對向量的長度進行縮放,且保持它的方向不變。在三維空間中進行縮放就是分別對 x、yz 軸進行縮放。咱們構造一個縮放矩陣,使得縮放矩陣乘以向量後,向量的每個份量都能乘以一個縮放因子。

注意這裏矩陣和向量的位置不能互換,否則結果就是一個 4 x 4 的矩陣了,而不是一個向量。

旋轉

上面兩種變換的計算相對容易理解,但旋轉稍微複雜些,特別是在三維空間中,物體能夠沿着 x、yz 軸旋轉。二維的旋轉僅能在平面上進行順時針或逆時針旋轉,所以相對簡單點,因此讓咱們從二維旋轉學起吧。

假設向量 P 的長度爲 r,角度是 ,將它逆時針旋轉 角,推導旋轉後的向量 P’ (x, y) 的參數方程爲:

寫成以下矩陣形式,其中

爲一個旋轉矩陣。

知道了二維空間中旋轉矩陣的推導後,咱們延伸到三維空間。在三維空間中,物體能夠沿着 x、yz 軸旋轉,以下圖所示:

從上圖能夠看到二維空間的旋轉跟三維空間沿 z 軸方向旋轉的效果是同樣的,xy 軸旋轉,z 軸保持不變

沿 x 軸旋轉爲,x 軸保持不變:

沿 y 軸旋轉爲,y 軸保持不變:

齊次座標

根據上面的討論,咱們能夠得出,對一個向量 平移、旋轉縮放 A 的仿射變換的通常公式爲:

固然,這個表達式還能夠進一步優化,咱們還能夠將平移變換也變成矩陣的形式,如何作呢?咱們將本來 n 維的座標轉換爲 n+1 維的座標。這種 n+1 維座標被稱爲齊次座標,對應的矩陣就被稱爲齊次矩陣。使用齊次座標後,平移矩陣以下表示:

對於縮放和旋轉只要保證新增的那一維 w1 便可,以下是齊次座標下的旋轉矩陣:

所以在齊次座標下,對一個向量 平移 、旋轉縮放 A 的仿射變換的通常公式爲:

矩陣的組合

使用矩陣來表示仿射變換,根據矩陣乘法,咱們能夠將多個變換組合到一個矩陣中。假設咱們有一個頂點 (x, y, z),咱們但願將其縮放 2 倍,而後位移 (1, 2, 3) 個單位。咱們須要一個位移和縮放矩陣來完成這些變換。因爲矩陣乘法不遵照交換律,當矩陣相乘時,最右邊的矩陣是第一個與向量相乘的,在組合矩陣時,通常先進行縮放,而後是旋轉,最後纔是位移,不然它們會互相影響。最終咱們的變換矩陣看起來是這樣:

總結

到此咱們學習完了向量和矩陣的一些基礎知識,爲咱們後面實現一些複雜的效果打下了基礎。回顧本節內容,一開始咱們學習了向量的基本運算,而後重點學習了向量的點乘和叉乘,由於這兩種運算在圖形學中有不少的應用。關於矩陣,咱們也學習了一些基礎運算,而後重點學習了矩陣和仿射變換,推導出了平移、縮放和旋轉矩陣,並介紹了這幾種旋轉矩陣在齊次座標下的表示形式。學完了這些基礎知識,咱們就能夠進入 3D 繪圖的世界啦。

參考資料:

  1. LearnOpenGL教程 變換
  2. 掘金小冊《WebGL 入門與實踐》數學基礎:點、向量、矩陣
  3. 極客時間《跟月影學可視化》如何用仿射變換對幾何圖形進行座標變換
相關文章
相關標籤/搜索