圖形學 旋轉與投影矩陣—1
game101 第二次作業; webgl 實現
使用 THREEJS 作為基礎框架,構建各類矩陣,自定義矩陣運算,最終完成
- 正確構建模型矩陣
- 正確構建透視投影矩陣
- 看到變換後的三角形
- 按 A 和 D 三角形能夠進行旋轉
- 按 Q 和 E 三角形能夠繞任意過原點的向量進行旋轉
最終效果
基礎變換
以二維座標系舉例,變換分為三種,縮放變換:能夠讓圖形寬高縮放指定倍數,旋轉變換:讓圖形繞原點逆時針旋轉任意角度,平移變換:讓影像向某個方向移動指定的量。下文描述三種變換的矩陣形式。
縮放變換
\[\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] \\
增加一個維度實現平移
\]
由於第二個思路可以轉換為矩陣相乘,與旋轉和縮放形式類似,因此最好選用思路二,統一運算公式 變換後點座標 = 變換矩陣 * 變換前座標
,選用思路二需要設定一些規則
- 點的表示 [x, y, 1]
- 向量的表示 [x, y, 0]
這樣做的好處就是不用單獨為平移變換計算變換的公式,全部採用通用公式,雖然增加了一個維度,但是計算起來更加方便,可以看出如下幾樣好處
- 分辨出了點和向量的差別
- 點 + 向量 = [2x, 2y, 1],依然是點,符合要求,減法也一樣
- 向量 + 向量 = [2x, 2y, 0],依然是向量,符合要求,減法也一樣
- 點 + 點 = [2x, 2y, 2],第三個引數預設是 1,因此它被等效於 [x, y, 1],這時還可以發現,求出的是兩點連線的中點,符合要求
結論
表示基礎變換時,我們可以用矩陣表示 縮放 和 旋轉 ,不能表示平移,為了能讓公式統一,多用了一個維度表示點的資訊,雖然多花費了一些空間,但是得到了更多的好處:分辨了點和向量,統一了計算公式
由於想輸出的太多,只寫一篇文章應該會太長,因此大概分為三篇,第一篇講在二維座標下的矩陣變換,第二篇和第三篇講在三維座標下的變換,檢視矩陣,投影矩陣的構造以及程式碼實現