文章目錄
- 平移、旋轉、縮放
-
- 平移
- 旋轉
-
- 1. 沿x軸旋轉
- 2. 沿y軸或者z軸旋轉
- 縮放
是時候整理一波3d變換相關的知識了。模型的變換可以認為是空間中一堆點的變換,三維空間中,(x,y,z)可以認為是點,也可以認為是一個向量,是以,人們引入的第4個次元來辨別是點還是向量,這個4維空間就叫 仿射空間,具體可以參考 CV及CG數學基礎:空間,在仿射空間中,(x,y,z,0)辨別向量,而(x,y,z,1)表示點。
平移、旋轉、縮放
平移
平移沒什麼好說的,(x,y,z,1)向x,y,z軸分别移動a,b,c機關長度後變成(x+a, y+b, z+c, 1)。寫成矩陣相乘的方式即為:
[ x + a y + b z + c 1 ] = [ 1 0 0 a 0 1 0 b 0 0 1 c 0 0 0 1 ] [ x y z 1 ] \left[ \begin{matrix} x+a \\ y+b \\ z+c \\ 1\\ \end{matrix} \right] = \left[ \begin{matrix} 1 & 0 & 0 & a\\ 0 & 1 & 0 & b \\ 0 & 0 & 1 & c \\ 0 & 0 & 0 & 1 \end{matrix} \right] \left[ \begin{matrix} x \\ y \\ z \\ 1\\ \end{matrix} \right] ⎣⎢⎢⎡x+ay+bz+c1⎦⎥⎥⎤=⎣⎢⎢⎡100001000010abc1⎦⎥⎥⎤⎣⎢⎢⎡xyz1⎦⎥⎥⎤
旋轉
對于旋轉,任何一個旋轉都可以認為是沿着x,y,z軸分别旋轉 α \alpha α, β \beta β, γ \gamma γ 度數,是以選旋轉就先講沿着某個軸向的旋轉。這裡以逆着坐标軸正向方向看去的順時針為旋轉的正向,就是你的視線朝向和坐标軸正向是相反的,(⊙o⊙)…我還是畫個圖吧,下圖就是沿着z軸旋轉的正向了哈~
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiclRnblN2XjlGcjAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHLsZFWlVnRXRGe1clWv50MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLzYzNwEDOxgTM2ITMxkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
1. 沿x軸旋轉
嗯!這裡推一波公式,其實很簡單,就是三角函數。
如上圖左邊,A點沿着x軸旋轉一定角度變成A’,為了更容易看,右圖是左圖的左視圖,記旋轉的角度為 θ \theta θ, 旋轉後得到的A’與旋轉中心連線與y軸正方向的夾角為 α \alpha α(圖中的 α \alpha α是個負值),記A’與旋轉中心連線的長度為L(A與旋轉中心連線的長度也是L),那麼,顯而易見,有:
x ′ = x y ′ = L ⋅ c o s ( θ + α ) z ′ = L ⋅ s i n ( θ + α ) \begin{aligned} x' =& x\\ y' =& L·cos(\theta + \alpha)\\ z' =& L·sin(\theta + \alpha) \end{aligned} x′=y′=z′=xL⋅cos(θ+α)L⋅sin(θ+α)
y = L ⋅ c o s α z = L ⋅ s i n α \begin{aligned} y =& L·cos\alpha\\ z =& L·sin\alpha \end{aligned} y=z=L⋅cosαL⋅sinα
根據三角函數公式可以得到
y ′ = L ⋅ c o s ( α − θ ) = L ⋅ ( c o s α c o s θ − s i n α s i n θ ) = y c o s θ − z s i n θ z ′ = L ⋅ s i n ( α − θ ) = L ⋅ ( s i n θ c o s α + c o s θ s i n α ) = y s i n θ + z c o s θ \begin{aligned} y' =& L·cos(\alpha - \theta) = L·(cos\alpha cos\theta - sin\alpha sin\theta) = ycos\theta -zsin\theta\\ z' =& L·sin(\alpha - \theta) = L·(sin\theta cos\alpha + cos\theta sin\alpha ) = ysin\theta + zcos\theta \end{aligned} y′=z′=L⋅cos(α−θ)=L⋅(cosαcosθ−sinαsinθ)=ycosθ−zsinθL⋅sin(α−θ)=L⋅(sinθcosα+cosθsinα)=ysinθ+zcosθ
綜上,有:
x ′ = x y ′ = y c o s θ − z s i n θ z ′ = y s i n θ + z c o s θ \begin{aligned} x' =& x\\ y' =& ycos\theta -zsin\theta\\ z' =&ysin\theta + zcos\theta \end{aligned} x′=y′=z′=xycosθ−zsinθysinθ+zcosθ
現在就可以寫成漂亮的矩陣形式了:
[ x ′ y ′ z ′ 1 ] = [ 1 0 0 0 0 c o s θ − s i n θ 0 0 s i n θ c o s θ 0 0 0 0 1 ] [ x y z 1 ] \left[ \begin{matrix} x' \\ y' \\ z' \\ 1\\ \end{matrix} \right] = \left[ \begin{matrix} 1 & 0 & 0 & 0\\ 0 & cos\theta & -sin\theta & 0 \\ 0 & sin\theta & cos\theta & 0 \\ 0 & 0 & 0 & 1 \end{matrix} \right] \left[ \begin{matrix} x \\ y \\ z \\ 1\\ \end{matrix} \right] ⎣⎢⎢⎡x′y′z′1⎦⎥⎥⎤=⎣⎢⎢⎡10000cosθsinθ00−sinθcosθ00001⎦⎥⎥⎤⎣⎢⎢⎡xyz1⎦⎥⎥⎤
2. 沿y軸或者z軸旋轉
推了x軸的,其他兩個軸向其實原理都是一樣的。
對于y軸,可以簡單把y軸和x軸對調,也就是公式裡的x,y對調,不過這樣子的話,z軸的方向會反過來,是以再把z相關的加個符号就好了。
公式如下:
y ′ = y x ′ = x c o s θ + z s i n θ z ′ = − x s i n θ + z c o s θ \begin{aligned} y' =& y\\ x' =& xcos\theta +zsin\theta\\ z' =&-xsin\theta +zcos\theta \end{aligned} y′=x′=z′=yxcosθ+zsinθ−xsinθ+zcosθ
寫成漂亮的矩陣形式就是:
[ x ′ y ′ z ′ 1 ] = [ c o s θ 0 s i n θ 0 0 1 0 0 − s i n θ 0 c o s θ 0 0 0 0 1 ] [ x y z 1 ] \left[ \begin{matrix} x' \\ y' \\ z' \\ 1\\ \end{matrix} \right] = \left[ \begin{matrix} cos\theta &0 & sin\theta & 0 \\ 0 & 1 & 0 & 0\\ -sin\theta & 0 & cos\theta & 0 \\ 0 & 0 & 0 & 1 \end{matrix} \right] \left[ \begin{matrix} x \\ y \\ z \\ 1\\ \end{matrix} \right] ⎣⎢⎢⎡x′y′z′1⎦⎥⎥⎤=⎣⎢⎢⎡cosθ0−sinθ00100sinθ0cosθ00001⎦⎥⎥⎤⎣⎢⎢⎡xyz1⎦⎥⎥⎤
對于z軸,x,z互換,y置反,直接上公式:
z ′ = z y ′ = y c o s θ + x s i n θ x ′ = − y s i n θ + x c o s θ \begin{aligned} z' =& z\\ y' =& ycos\theta +xsin\theta\\ x' =&-ysin\theta + xcos\theta \end{aligned} z′=y′=x′=zycosθ+xsinθ−ysinθ+xcosθ
矩陣形式:
[ x ′ y ′ z ′ 1 ] = [ c o s θ − s i n θ 0 0 s i n θ c o s θ 0 0 0 0 1 0 0 0 0 1 ] [ x y z 1 ] \left[ \begin{matrix} x' \\ y' \\ z' \\ 1\\ \end{matrix} \right] = \left[ \begin{matrix} cos\theta & -sin\theta&0 & 0 \\ sin\theta & cos\theta & 0 & 0 \\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & 1 \end{matrix} \right] \left[ \begin{matrix} x \\ y \\ z \\ 1\\ \end{matrix} \right] ⎣⎢⎢⎡x′y′z′1⎦⎥⎥⎤=⎣⎢⎢⎡cosθsinθ00−sinθcosθ0000100001⎦⎥⎥⎤⎣⎢⎢⎡xyz1⎦⎥⎥⎤
那一個物體沿着x,y,z 軸分别旋轉 α \alpha α, β \beta β, γ \gamma γ 度數就把3個矩陣相乘就好了。
[ x ′ y ′ z ′ 1 ] = [ c o s γ − s i n γ 0 0 s i n γ c o s γ 0 0 0 0 1 0 0 0 0 1 ] [ c o s β 0 s i n β 0 0 1 0 0 − s i n β 0 c o s β 0 0 0 0 1 ] [ 1 0 0 0 0 c o s α − s i n α 0 0 s i n α c o s α 0 0 0 0 1 ] [ x y z 1 ] \left[ \begin{matrix} x' \\ y' \\ z' \\ 1\\ \end{matrix} \right] = \left[ \begin{matrix} cos\gamma& -sin\gamma&0 & 0 \\ sin\gamma& cos\gamma& 0 & 0 \\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & 1 \end{matrix} \right] \left[ \begin{matrix} cos\beta&0 & sin\beta& 0 \\ 0 & 1 & 0 & 0\\ -sin\beta& 0 & cos\beta& 0 \\ 0 & 0 & 0 & 1 \end{matrix} \right] \left[ \begin{matrix} 1 & 0 & 0 & 0\\ 0 & cos\alpha & -sin\alpha & 0 \\ 0 & sin\alpha & cos\alpha & 0 \\ 0 & 0 & 0 & 1 \end{matrix} \right] \left[ \begin{matrix} x \\ y \\ z \\ 1\\ \end{matrix} \right] ⎣⎢⎢⎡x′y′z′1⎦⎥⎥⎤=⎣⎢⎢⎡cosγsinγ00−sinγcosγ0000100001⎦⎥⎥⎤⎣⎢⎢⎡cosβ0−sinβ00100sinβ0cosβ00001⎦⎥⎥⎤⎣⎢⎢⎡10000cosαsinα00−sinαcosα00001⎦⎥⎥⎤⎣⎢⎢⎡xyz1⎦⎥⎥⎤
[ x ′ y ′ z ′ 1 ] = [ c o s β c o s γ s i n α s i n β c o s γ − s i n γ c o s α s i n β c o s α c o s γ + s i n α s i n γ 0 c o s β s i n γ c o s α c o s γ + s i n α s i n β s i n γ − s i n α c o s γ + s i n γ s i n β c o s α 0 − s i n β s i n α c o s β c o s α c o s β 0 0 0 0 1 ] [ x y z 1 ] \left[ \begin{matrix} x' \\ y' \\ z' \\ 1\\ \end{matrix} \right] = \left[ \begin{matrix} cos\beta cos\gamma & sin\alpha sin\beta cos\gamma - sin\gamma cos\alpha & sin\beta cos\alpha cos\gamma +sin\alpha sin\gamma & 0\\ cos\beta sin\gamma & cos\alpha cos\gamma + sin\alpha sin\beta sin\gamma & -sin\alpha cos\gamma + sin\gamma sin\beta cos\alpha & 0 \\ -sin\beta & sin\alpha cos\beta& cos\alpha cos\beta& 0 \\ 0 & 0 & 0 & 1 \end{matrix} \right] \left[ \begin{matrix} x \\ y \\ z \\ 1\\ \end{matrix} \right] ⎣⎢⎢⎡x′y′z′1⎦⎥⎥⎤=⎣⎢⎢⎡cosβcosγcosβsinγ−sinβ0sinαsinβcosγ−sinγcosαcosαcosγ+sinαsinβsinγsinαcosβ0sinβcosαcosγ+sinαsinγ−sinαcosγ+sinγsinβcosαcosαcosβ00001⎦⎥⎥⎤⎣⎢⎢⎡xyz1⎦⎥⎥⎤
縮放
縮放感覺也沒的說,直接上公示,下面公式表示沿着x,y,z軸分别縮放a,b,c倍:
[ x ′ y ′ z ′ 1 ] = [ a 0 0 0 0 b 0 0 0 0 c 0 0 0 0 1 ] [ x y z 1 ] \left[ \begin{matrix} x' \\ y' \\ z' \\ 1\\ \end{matrix} \right] = \left[ \begin{matrix} a & 0 & 0 & 0\\ 0 & b & 0 & 0 \\ 0 & 0 & c & 0 \\ 0 & 0 & 0 & 1 \end{matrix} \right] \left[ \begin{matrix} x \\ y \\ z \\ 1\\ \end{matrix} \right] ⎣⎢⎢⎡x′y′z′1⎦⎥⎥⎤=⎣⎢⎢⎡a0000b0000c00001⎦⎥⎥⎤⎣⎢⎢⎡xyz1⎦⎥⎥⎤