圖形學 旋轉與投影矩陣—1

隨遇丿而安發表於2021-12-23

圖形學 旋轉與投影矩陣—1

game101 第二次作業; webgl 實現

使用 THREEJS 作為基礎框架,構建各類矩陣,自定義矩陣運算,最終完成

  1. 正確構建模型矩陣
  2. 正確構建透視投影矩陣
  3. 看到變換後的三角形
  4. 按 A 和 D 三角形能夠進行旋轉
  5. 按 Q 和 E 三角形能夠繞任意過原點的向量進行旋轉

最終效果

第1次作業-最終效果

基礎變換

以二維座標系舉例,變換分為三種,縮放變換:能夠讓圖形寬高縮放指定倍數,旋轉變換:讓圖形繞原點逆時針旋轉任意角度,平移變換:讓影像向某個方向移動指定的量。下文描述三種變換的矩陣形式。

縮放變換

\[\left[ \begin{matrix} x' \\ y ' \end{matrix} \right] = \left[ \begin{matrix} S_x & 0 \\ 0 & S_y \end{matrix} \right] \times \left[ \begin{matrix} x \\ y \end{matrix} \right] \\ 公式一: 旋轉矩陣變換 \]

變換後的座標簡單寫成 [x‘, y’] (實際上所有的座標都是以列向量進行儲存,這裡特別說明),變換前的座標為 [x, y]。變換時的數值運算如下

\[\left\{ \begin{array}{} x'=S_x \times x \\ y'=S_y \times y \end{array} \right. \\ 公式一補充 \\ S_x: 表示寬縮放比例 \\ S_y: 表示高縮放比例 \]

表示縮放就可以用 [Sx, Sy] ,對應矩陣為公式一中的旋轉矩陣

旋轉變換

旋轉變換求解相對困難,此時可以採用代點求值,如下所示

第二次作業-圖一

有個大小為 1*1 的正方形繞原點旋轉 θ 角度得到第二個正方形,圖上標示了兩個紅點,這兩個紅點就是可以代入進行計算的點,將旋轉前的 [x, y] 與旋轉後的 [x', y'] 代入下述方程中,解出旋轉變換矩陣

\[設定旋轉矩陣的每個引數分別為\: a, b, c, d \\ 第一步: 列出方程\\ \left[ \begin{matrix} x' \\ y ' \end{matrix} \right] = \left[ \begin{matrix} a & b \\ c & d \end{matrix} \right] \times \left[ \begin{matrix} x \\ y \end{matrix} \right] \\ \\ 第二步:代入兩個代表點的變換\\ \left[ \begin{matrix} 1 \\ 0 \end{matrix} \right] = \left[ \begin{matrix} a & b \\ c & d \end{matrix} \right] \times \left[ \begin{matrix} \cos(\theta) \\ \sin(\theta) \end{matrix} \right] \\ \\ \left[ \begin{matrix} 0 \\ 1 \end{matrix} \right] = \left[ \begin{matrix} a & b \\ c & d \end{matrix} \right] \times \left[ \begin{matrix} -\sin(\theta) \\ \cos(\theta) \end{matrix} \right] \\ \\ 第三步: 得到結果 \\ \left[ \begin{matrix} a & b \\ c & d \end{matrix} \right] = \left[ \begin{matrix} \cos(\theta) & -\sin(\theta) \\ \sin(\theta) & \cos(\theta) \end{matrix} \right] \\ \\ \left[ \begin{matrix} x' \\ y ' \end{matrix} \right] = \left[ \begin{matrix} \cos(\theta) & -\sin(\theta) \\ \sin(\theta) & \cos(\theta) \end{matrix} \right] \times \left[ \begin{matrix} x \\ y \end{matrix} \right] \]

由於採用代入法求解,將 [0, 1] 和 [1, 0] 點代入方程,最終求得了旋轉矩陣中 a, b, c, d 的值。旋轉矩陣求解的問題就得到了解決。

平移變換

由前兩節可以看出來,將一個點設為 [x, y],將其與 2*2 的矩陣相乘,是無法得到 [x+a, y+b] 的代數式,只能得到 [a*x, b*y] 這種形式的座標

針對 2*2 的矩陣無法求得 [x+a, y+b] 形式的座標問題,有兩種解決方法,思路如下

\[思路一: \: \left[ \begin{matrix} x' \\ y ' \end{matrix} \right] = \left[ \begin{matrix} x \\ y \end{matrix} \right] + \left[ \begin{matrix} t_x \\ t_y \end{matrix} \right] \\ t_x: 在x軸上移動的距離 \\ t_y: 在y軸上移動的距離 \\ \\ 思路二: \: \left[ \begin{matrix} x' \\ y ' \\ 1 \end{matrix} \right] = \left[ \begin{matrix} 1 & 0 & t_x \\ 0 & 1 & t_y \\ 0 & 0 & 1 \end{matrix} \right] \times \left[ \begin{matrix} x \\ y \\ 1 \end{matrix} \right] \\ 增加一個維度實現平移 \]

由於第二個思路可以轉換為矩陣相乘,與旋轉和縮放形式類似,因此最好選用思路二,統一運算公式 變換後點座標 = 變換矩陣 * 變換前座標,選用思路二需要設定一些規則

  1. 點的表示 [x, y, 1]
  2. 向量的表示 [x, y, 0]

這樣做的好處就是不用單獨為平移變換計算變換的公式,全部採用通用公式,雖然增加了一個維度,但是計算起來更加方便,可以看出如下幾樣好處

  1. 分辨出了點和向量的差別
  2. 點 + 向量 = [2x, 2y, 1],依然是點,符合要求,減法也一樣
  3. 向量 + 向量 = [2x, 2y, 0],依然是向量,符合要求,減法也一樣
  4. 點 + 點 = [2x, 2y, 2],第三個引數預設是 1,因此它被等效於 [x, y, 1],這時還可以發現,求出的是兩點連線的中點,符合要求

結論

表示基礎變換時,我們可以用矩陣表示 縮放 和 旋轉 ,不能表示平移,為了能讓公式統一,多用了一個維度表示點的資訊,雖然多花費了一些空間,但是得到了更多的好處:分辨了點和向量,統一了計算公式

由於想輸出的太多,只寫一篇文章應該會太長,因此大概分為三篇,第一篇講在二維座標下的矩陣變換,第二篇和第三篇講在三維座標下的變換,檢視矩陣,投影矩陣的構造以及程式碼實現

相關文章