三维变换
与二维变换类似,可以在齐次坐标下,将三维向量变成四维向量:
点:
(
x
,
y
,
z
,
1
)
T
(x,y,z,1)^T
(x,y,z,1)T
向量:
(
x
,
y
,
z
,
0
)
T
(x,y,z,0)^T
(x,y,z,0)T
同样的,在齐次坐标下,当
w
≠
0
w\neq0
w=0时,我们认为
(
x
,
y
,
z
,
w
)
(x,y,z,w)
(x,y,z,w)表示点
(
x
/
w
,
y
/
w
,
z
/
w
)
(x/w,y/w,z/w)
(x/w,y/w,z/w)。
-
仿射变换矩阵
( x ′ y ′ z ′ 1 ) = ( a b c t x d e f t y g h i t z 0 0 0 1 ) ⋅ ( x y z 1 ) \begin{pmatrix}x^\prime\\y^\prime\\z^\prime\\1\end{pmatrix}=\begin{pmatrix}a&b&c&t_x\\d&e&f&t_y\\g&h&i&t_z\\0&0&0&1\end{pmatrix}\cdot\begin{pmatrix}x\\y\\z\\1\end{pmatrix} ⎝⎜⎜⎛x′y′z′1⎠⎟⎟⎞=⎝⎜⎜⎛adg0beh0cfi0txtytz1⎠⎟⎟⎞⋅⎝⎜⎜⎛xyz1⎠⎟⎟⎞
当我们用一个矩阵进行变换时,是先进行线性变换(旋转、缩放、错切)再进行平移。 -
缩放矩阵
S ( s x , s y , s z ) = ( s x 0 0 0 0 s y 0 0 0 0 s z 0 0 0 0 1 ) \mathbf{S}(s_x,s_y,s_z)=\begin{pmatrix}s_x&0&0&0\\0&s_y&0&0\\0&0&s_z&0\\0&0&0&1\end{pmatrix} S(sx,sy,sz)=⎝⎜⎜⎛sx0000sy0000sz00001⎠⎟⎟⎞ -
平移矩阵
T ( t x , t y , t z ) = ( 1 0 0 t x 0 1 0 t y 0 0 1 t z 0 0 0 1 ) \mathbf{T}(t_x,t_y,t_z)=\begin{pmatrix}1&0&0&t_x\\0&1&0&t_y\\0&0&1&t_z\\0&0&0&1\end{pmatrix} T(tx,ty,tz)=⎝⎜⎜⎛100001000010txtytz1⎠⎟⎟⎞ -
旋转矩阵
-
绕X轴旋转
R x ( α ) = ( 1 0 0 0 0 cos α − sin α 0 0 sin α cos α 0 0 0 0 1 ) \mathbf{R}_x(\alpha)=\begin{pmatrix}1&0&0&0\\0&\cos\alpha&-\sin\alpha&0\\0&\sin\alpha&\cos\alpha&0\\0&0&0&1\end{pmatrix} Rx(α)=⎝⎜⎜⎛10000cosαsinα00−sinαcosα00001⎠⎟⎟⎞ -
绕Y轴旋转
R
y
(
α
)
=
(
cos
α
0
sin
α
0
0
1
0
0
−
sin
α
0
cos
α
0
0
0
0
1
)
\mathbf{R}_y(\alpha)=\begin{pmatrix}\cos\alpha&0&\sin\alpha&0\\0&1&0&0\\-\sin\alpha&0&\cos\alpha&0\\0&0&0&1\end{pmatrix}
Ry(α)=⎝⎜⎜⎛cosα0−sinα00100sinα0cosα00001⎠⎟⎟⎞
这里绕Y轴旋转与其他两个有点不一样,可以看到
−
sin
α
-\sin\alpha
−sinα和
sin
α
\sin\alpha
sinα位置是互换的,这是因为无论是X轴还是Z轴,通过其他两个轴叉乘获得时都是按照右手螺旋定则得到的,而Y轴则是通过左手螺旋定则获得,所以与其余两个矩阵有一点差别。
R z ( α ) = ( cos α − sin α 0 0 sin α cos α 0 0 0 0 1 0 0 0 0 1 ) \mathbf{R}_z(\alpha)=\begin{pmatrix}\cos\alpha&-\sin\alpha&0&0\\\sin\alpha&\cos\alpha&0&0\\0&0&1&0\\0&0&0&1\end{pmatrix} Rz(α)=⎝⎜⎜⎛cosαsinα00−sinαcosα0000100001⎠⎟⎟⎞
R
(
n
,
α
)
=
cos
(
α
)
I
+
(
1
−
cos
(
α
)
)
n
n
T
+
sin
(
α
)
(
0
−
n
z
n
y
n
z
0
−
n
x
−
n
y
n
x
0
)
⏟
N
\mathbf{R}(\mathbf{n},\alpha)=\cos(\alpha)\mathbf{I}+(1-\cos(\alpha))\mathbf{nn}^T+\sin(\alpha)\underbrace{\begin{pmatrix}0&-n_z&n_y\\n_z&0&-n_x\\-n_y&n_x&0\end{pmatrix}}_N
R(n,α)=cos(α)I+(1−cos(α))nnT+sin(α)N
⎝⎛0nz−ny−nz0nxny−nx0⎠⎞
这里,我们认为这里的旋转轴
n
\mathbf{n}
n是过原点的,如果我们需要计算绕着不经过原点的轴旋转,那么可以先平移到原点,再进行旋转,最后平移回去就可以了。
视图变换矩阵MVP(Model - View - Projection)。
以相机为原点,相机向上方向为
t
^
\hat{t}
t^,相机朝向为
g
^
\hat{g}
g^,
g
^
×
t
^
\hat{g}\times\hat{t}
g^×t^ 为
e
^
\hat{e}
e^。将模型空间内的物体转换到相机空间,其实就相当于将相机的
e
^
\hat{e}
e^ 移动旋转到X轴,
g
^
\hat{g}
g^ 移动旋转到Y轴,
t
^
\hat{t}
t^ 移动旋转到Z轴,同时,物体会与相机保持相对静止。
那么变换矩阵
M
v
i
e
w
=
R
v
i
e
w
T
v
i
e
w
M_{view}=R_{view}T_{view}
Mview=RviewTview,我们先进行平移
T
v
i
e
w
=
[
1
0
0
−
x
e
0
1
0
−
y
e
0
0
1
−
z
e
0
0
0
1
]
T_{view}=\begin{bmatrix}1&0&0&-x_e\\0&1&0&-y_e\\0&0&1&-z_e\\0&0&0&1\end{bmatrix}
Tview=⎣⎢⎢⎡100001000010−xe−ye−ze1⎦⎥⎥⎤然后,再将对应的轴旋转过去。这里我们如果直接写将
e
^
g
^
t
^
\hat{e}\hat{g}\hat{t}
e^g^t^ 旋转到XYZ的矩阵会比较困难,我们之前提到过,旋转矩阵是一个正交矩阵,所以他的逆矩阵和转置矩阵是相等的,我们可以使用这个性质。直接写出从XYZ旋转到
e
^
g
^
t
^
\hat{e}\hat{g}\hat{t}
e^g^t^ 的旋转矩阵
R
v
i
e
w
−
1
=
[
x
g
^
×
t
^
x
t
x
−
g
0
y
g
^
×
t
^
y
t
y
−
g
0
z
g
^
×
t
^
z
t
z
−
g
0
0
0
0
1
]
R^{-1}_{view}=\begin{bmatrix}x_{\hat{g}\times\hat{t}}&x_t&x_{-g}&0\\y_{\hat{g}\times\hat{t}}&y_t&y_{-g}&0\\z_{\hat{g}\times\hat{t}}&z_t&z_{-g}&0\\0&0&0&1\end{bmatrix}
Rview−1=⎣⎢⎢⎡xg^×t^yg^×t^zg^×t^0xtytzt0x−gy−gz−g00001⎦⎥⎥⎤
然后,
R
v
i
e
w
=
(
R
v
i
e
w
−
1
)
−
1
=
(
R
v
i
e
w
−
1
)
T
=
[
x
g
^
×
t
^
y
g
^
×
t
^
z
g
^
×
t
^
0
x
t
y
t
z
t
0
x
−
g
y
−
g
z
−
g
0
0
0
0
1
]
R_{view}=(R^{-1}_{view})^{-1}=(R^{-1}_{view})^T=\begin{bmatrix}x_{\hat{g}\times\hat{t}}&y_{\hat{g}\times\hat{t}}&z_{\hat{g}\times\hat{t}}&0\\x_t&y_t&z_t&0\\x_{-g}&y_{-g}&z_{-g}&0\\0&0&0&1\end{bmatrix}
Rview=(Rview−1)−1=(Rview−1)T=⎣⎢⎢⎡xg^×t^xtx−g0yg^×t^yty−g0zg^×t^ztz−g00001⎦⎥⎥⎤
-
投影变换
投影分为正交投影(Orthographic Projection)和透视投影(Perspective Projection)。 -
正交投影
将相机摆在原点,看向-Z轴方向,向上方向朝向Y轴,然后将Z轴去掉,然后将区间缩放到 [ − 1 , 1 ] 2 [-1,1]^2 [−1,1]2 之间,就获得了正交投影的结果。
在图形学中,我们定义一个立方体 [ l , r ] × [ b , t ] × [ f , n ] ( l 左 , r 右 , b 下 , t 上 , f 远 , n 近 ; 这 里 因 为 我 们 是 看 向 − Z 方 向 的 , 所 以 n 的 值 比 f 大 ) [l,r]\times[b,t]\times[f,n](l左,r右,b下,t上,f远,n近;这里因为我们是看向-Z方向的,所以 n 的值比 f 大) [l,r]×[b,t]×[f,n](l左,r右,b下,t上,f远,n近;这里因为我们是看向−Z方向的,所以n的值比f大),将这个立方体通过变换,得到一个中心在原点,范围在 [ − 1 , 1 ] 3 [-1,1]^3 [−1,1]3 的立方体,这个过程就是正交变换。
变换矩阵 M o r t h o = [ 2 r − t 0 0 0 0 2 t − b 0 0 0 0 2 n − f 0 0 0 0 1 ] [ 1 0 0 − r + l 2 0 1 0 − t + b 2 0 0 1 − n + f 2 0 0 0 1 ] = [ 2 r − t 0 0 − r + l 2 0 2 t − b 0 − t + b 2 0 0 2 n − f − n + f 2 0 0 0 1 ] M_{ortho}=\begin{bmatrix}\frac{2}{r-t}&0&0&0\\0&\frac{2}{t-b}&0&0\\0&0&\frac{2}{n-f}&0\\0&0&0&1\end{bmatrix}\begin{bmatrix}1&0&0&-\frac{r+l}{2}\\0&1&0&-\frac{t+b}{2}\\0&0&1&-\frac{n+f}{2}\\0&0&0&1\end{bmatrix}=\begin{bmatrix}\frac{2}{r-t}&0&0&-\frac{r+l}{2}\\0&\frac{2}{t-b}&0&-\frac{t+b}{2}\\0&0&\frac{2}{n-f}&-\frac{n+f}{2}\\0&0&0&1\end{bmatrix} Mortho=⎣⎢⎢⎡r−t20000t−b20000n−f200001⎦⎥⎥⎤⎣⎢⎢⎡100001000010−2r+l−2t+b−2n+f1⎦⎥⎥⎤=⎣⎢⎢⎡r−t20000t−b20000n−f20−2r+l−2t+b−2n+f1⎦⎥⎥⎤ -
透视投影
透视投影的立方体中,远平面 f f f 比近平面 n n n 的面积大,我们可以将远平面缩放到与近平面一样大,这样就可以将透视投影转换为正交投影了。
由相似三角形的原理可以得到这个立方体中的任意一点 ( x , y , z , 1 ) (x,y,z,1) (x,y,z,1) 通过压缩,再统一乘以 z z z 可以得到 ( x ′ y ′ z ′ 1 ) = ( n x z n y z ? 1 ) = ( n x n y ? z ) \begin{pmatrix}x^\prime\\y^\prime\\z^\prime\\1\end{pmatrix}=\begin{pmatrix}\frac{nx}{z}\\\frac{ny}{z}\\?\\1\end{pmatrix}=\begin{pmatrix}nx\\ny\\?\\z\end{pmatrix} ⎝⎜⎜⎛x′y′z′1⎠⎟⎟⎞=⎝⎜⎜⎛znxzny?1⎠⎟⎟⎞=⎝⎜⎜⎛nxny?z⎠⎟⎟⎞
那么,我们就可以定义一个矩阵 M p e r s p → o r t h o M_{persp\to ortho} Mpersp→ortho,满足
M p e r s p → o r t h o ( x y z 1 ) = ( n x n y ? z ) M_{persp\to ortho}\begin{pmatrix}x\\y\\z\\1\end{pmatrix}=\begin{pmatrix}nx\\ny\\?\\z\end{pmatrix} Mpersp→ortho⎝⎜⎜⎛xyz1⎠⎟⎟⎞=⎝⎜⎜⎛nxny?z⎠⎟⎟⎞
由此,可以计算出
M p e r s p → o r t h o = ( n 0 0 0 0 n 0 0 ? ? ? ? 0 0 1 0 ) M_{persp\to ortho}=\begin{pmatrix}n&0&0&0\\0&n&0&0\\?&?&?&?\\0&0&1&0\end{pmatrix} Mpersp→ortho=⎝⎜⎜⎛n0?00n?000?100?0⎠⎟⎟⎞
为了计算出第三行,我们可以取两个特殊的点,首先,近平面上的点肯定也满足这个转换条件,并且近平面上的点通过转换后与原来的相同,我们知道,近平面上的点的 z = n z=n z=n,所以
( x ′ y ′ z ′ 1 ) = ( n x n y ? z ) = M p e r s p → o r t h o ( x y z 1 ) = M p e r s p → o r t h o ( x y n 1 ) = ( n x n y n 2 n ) \begin{pmatrix}x^\prime\\y^\prime\\z^\prime\\1\end{pmatrix}=\begin{pmatrix}nx\\ny\\?\\z\end{pmatrix}=M_{persp\to ortho} \begin{pmatrix}x\\y\\z\\1\end{pmatrix}=M_{persp\to ortho}\begin{pmatrix}x\\y\\n\\1\end{pmatrix}=\begin{pmatrix}nx\\ny\\n^2\\n\end{pmatrix} ⎝⎜⎜⎛x′y′z′1⎠⎟⎟⎞=⎝⎜⎜⎛nxny?z⎠⎟⎟⎞=Mpersp→ortho⎝⎜⎜⎛xyz1⎠⎟⎟⎞=Mpersp→ortho⎝⎜⎜⎛xyn1⎠⎟⎟⎞=⎝⎜⎜⎛nxnyn2n⎠⎟⎟⎞
从上式可以得出,矩阵的第三行为 ( 0 0 A B ) \begin{pmatrix}0&0&A&B\end{pmatrix} (00AB) ,
( 0 0 A B ) ( x y n 1 ) = n 2 \begin{pmatrix}0&0&A&B\end{pmatrix}\begin{pmatrix}x\\y\\n\\1\end{pmatrix}=n^2 (00AB)⎝⎜⎜⎛xyn1⎠⎟⎟⎞=n2
由此可得 A n + B = n 2 (1) An+B=n^2 \tag{1} An+B=n2(1)
再则,我们都知道,远平面上的点通过变换之后, z z z 值是不变的,并且远平面上的点的 z = f z=f z=f,我们取远平面上的一个特殊的点 ( 0 0 f 1 ) T \begin{pmatrix}0&0&f&1\end{pmatrix}^T (00f1)T,经过变换之后,依然等于这个点,
M p e r s p → o r t h o ( 0 0 f 1 ) = ( 0 0 f 1 ) = = f ⋅ ( 0 0 f 1 ) = ( 0 0 f 2 f ) M_{persp\to ortho}\begin{pmatrix}0\\0\\f\\1\end{pmatrix}=\begin{pmatrix}0\\0\\f\\1\end{pmatrix}==f\cdot\begin{pmatrix}0\\0\\f\\1\end{pmatrix}=\begin{pmatrix}0\\0\\f^2\\f\end{pmatrix} Mpersp→ortho⎝⎜⎜⎛00f1⎠⎟⎟⎞=⎝⎜⎜⎛00f1⎠⎟⎟⎞==f⋅⎝⎜⎜⎛00f1⎠⎟⎟⎞=⎝⎜⎜⎛00f2f⎠⎟⎟⎞
由此可得 A f + B = f 2 (2) Af+B=f^2\tag{2} Af+B=f2(2)
由 ( 1 ) ( 2 ) (1)(2) (1)(2)式可解出 A = n + f B = − n f A=n+f\\B=-nf A=n+fB=−nf
于是,从透视空间变化到正交空间的变换矩阵为
M p e r s p → o r t h o = [ n 0 0 0 0 n 0 0 0 0 n + f − n f 0 0 1 0 ] M_{persp\to ortho}=\begin{bmatrix}n&0&0&0\\0&n&0&0\\0&0&n+f&-nf\\0&0&1&0\end{bmatrix} Mpersp→ortho=⎣⎢⎢⎡n0000n0000n+f100−nf0⎦⎥⎥⎤
最终可得,透视变换的矩阵为
M p e r s p = M o r t h o M p e r s p → o r t h o = [ 2 r − t 0 0 − r + l 2 0 2 t − b 0 − t + b 2 0 0 2 n − f − n + f 2 0 0 0 1 ] [ n 0 0 0 0 n 0 0 0 0 n + f − n f 0 0 1 0 ] M_{persp}=M_{ortho}M_{persp\to ortho}=\begin{bmatrix}\frac{2}{r-t}&0&0&-\frac{r+l}{2}\\0&\frac{2}{t-b}&0&-\frac{t+b}{2}\\0&0&\frac{2}{n-f}&-\frac{n+f}{2}\\0&0&0&1\end{bmatrix}\begin{bmatrix}n&0&0&0\\0&n&0&0\\0&0&n+f&-nf\\0&0&1&0\end{bmatrix} Mpersp=MorthoMpersp→ortho=⎣⎢⎢⎡r−t20000t−b20000n−f20−2r+l−2t+b−2n+f1⎦⎥⎥⎤⎣⎢⎢⎡n0000n0000n+f100−nf0⎦⎥⎥⎤