图形学基础-变换
-
2D transformations: rotation, scale, shear
-
Homogeneous coordinates(齐次坐标)
-
Composite transform(变换复合)
-
3D transformations(3D变换)
-
Viewing (观测) transformation(视图变换相关)
- View (视图) /Camera transformation (视图变换)
- Projection (投影) transformation
- Orthographic (正交) projection (正交投影)
- Perspective (透视) projection (透视投影)
2D线性变换
缩放(Scale)
Scale(sx,sy)=[sx00sy][sx00sy]∗[xy]=[sxxsyy]
Scale(s_x,s_y) =\begin{bmatrix}
s_x & 0 \\
0 & s_y
\end{bmatrix}\\
\begin{bmatrix}
s_x & 0 \\
0 & s_y
\end{bmatrix}*
\begin{bmatrix}
x\\
y
\end{bmatrix}=
\begin{bmatrix}
s_xx\\
s_yy
\end{bmatrix}
Scale(sx,sy)=[sx00sy][sx00sy]∗[xy]=[sxxsyy]
错切(Shear)
shear_x(s)=[1s01],shear_y(s)=[1001][10s1]∗[xy]=[xsx+y]
shear\_x(s) =\begin{bmatrix}
1 & s \\
0 & 1
\end{bmatrix},
shear\_y(s) =\begin{bmatrix}
1 & 0 \\
0 & 1
\end{bmatrix}\\
\begin{bmatrix}
1 & 0 \\
s & 1
\end{bmatrix}*
\begin{bmatrix}
x\\
y
\end{bmatrix}=
\begin{bmatrix}
x\\
sx+y
\end{bmatrix}
shear_x(s)=[10s1],shear_y(s)=[1001][1s01]∗[xy]=[xsx+y]
旋转(rotation)
rotation(ϕ)=[cosϕ−sinϕsinϕcosϕ][cosϕ−sinϕsinϕcosϕ]∗[xy]=[xcosϕ−ysinϕxsinϕ+ycosϕ]
rotation(\phi) =\begin{bmatrix}
\cos{\phi} & -\sin{\phi} \\
\sin{\phi} & \cos{\phi}
\end{bmatrix}\\
\begin{bmatrix}
\cos{\phi} & -\sin{\phi} \\
\sin{\phi} & \cos{\phi}
\end{bmatrix}*
\begin{bmatrix}
x\\
y
\end{bmatrix}=
\begin{bmatrix}
x\cos{\phi}-y\sin{\phi}\\
x\sin{\phi}+y\cos{\phi}
\end{bmatrix}
rotation(ϕ)=[cosϕsinϕ−sinϕcosϕ][cosϕsinϕ−sinϕcosϕ]∗[xy]=[xcosϕ−ysinϕxsinϕ+ycosϕ]
这旋转矩阵表示将向量(或点)绕原点逆时针旋转ϕ\phiϕ。
翻转(reflection)
reflect_x=[−1001],reflect_y=[100−1][−1001]∗[xy]= reflect\_x =\begin{bmatrix} -1 & 0 \\ 0 & 1 \end{bmatrix}, reflect\_y =\begin{bmatrix} 1 & 0 \\ 0 & -1 \end{bmatrix}\\ \begin{bmatrix} -1 & 0 \\ 0 & 1 \end{bmatrix}* \begin{bmatrix} x\\ y \end{bmatrix}= reflect_x=[−1001],reflect_y=[100−1][−1001]∗[xy]=
平移(Translation)
平移能否使用2维矩阵表示吗?
**对于任意一个点的平移(向量具有平移不变性)**它有如下形式
xt=x+tx;yt=y+ty
x_t = x+t_x;y_t=y+t_y
xt=x+tx;yt=y+ty
平移无法使用一个2x2的矩阵来表示!因此引入齐次坐标
齐次坐标(Homogeneous coordinates)
给二维点或向量增加一个维度:
2D向量:(x,y)T=>(x,y,0)T(x,y)^T=>(x,y,0)^T(x,y)T=>(x,y,0)T
2D点 :(x,y)T=>(x,y,1)T(x,y)^T=>(x,y,1)^T(x,y)T=>(x,y,1)T
对于2D点 :(x,y,w)T=>(x/w,y/w)Tw!=0(x,y,w)^T=>(x/w,y/w)^Tw!=0(x,y,w)T=>(x/w,y/w)Tw!=0。
则平移可以表示为:
Translation=[10tx01ty001][10tx01ty001]∗[xy1]=[x+txy+ty1](point)[10tx01ty001]∗[xy0]=[xy0](vector)
Translation =\begin{bmatrix}
1 & 0 & t_x\\
0 & 1 & t_y\\
0 & 0 & 1
\end{bmatrix}\\
\begin{bmatrix}
1 & 0 & t_x\\
0 & 1 & t_y\\
0 & 0 & 1
\end{bmatrix}*
\begin{bmatrix}
x\\
y\\
1
\end{bmatrix}=
\begin{bmatrix}
x+t_x\\
y+t_y\\
1
\end{bmatrix}(point)\\
\begin{bmatrix}
1 & 0 & t_x\\
0 & 1 & t_y\\
0 & 0 & 1
\end{bmatrix}*
\begin{bmatrix}
x\\
y\\
0
\end{bmatrix}=
\begin{bmatrix}
x\\
y\\
0
\end{bmatrix}(vector)
Translation=⎣⎡100010txty1⎦⎤⎣⎡100010txty1⎦⎤∗⎣⎡xy1⎦⎤=⎣⎡x+txy+ty1⎦⎤(point)⎣⎡100010txty1⎦⎤∗⎣⎡xy0⎦⎤=⎣⎡xy0⎦⎤(vector)
这样就可以将旋转,平移,错切等等放入同一个维度的矩阵去表示。
仿射变换(Affine Transformations)
仿射变换就是指线性变换与平移的组合:
[abcd]∗[xy]+[txty]=[ax+by+txcx+dy+ty]
\begin{bmatrix}
a & b \\
c & d
\end{bmatrix}*
\begin{bmatrix}
x\\
y
\end{bmatrix}+
\begin{bmatrix}
t_x\\
t_y
\end{bmatrix}=
\begin{bmatrix}
ax+by+t_x\\
cx+dy+t_y
\end{bmatrix}
[acbd]∗[xy]+[txty]=[ax+by+txcx+dy+ty]
利用齐次坐标可以写成一个三维矩阵:
[abtxcdty001]∗[xy1]=[ax+by+txcx+dy+ty1](point)
\begin{bmatrix}
a & b & t_x\\
c & d & t_y\\
0 & 0 & 1
\end{bmatrix}*
\begin{bmatrix}
x\\
y\\
1
\end{bmatrix}=
\begin{bmatrix}
ax+by+t_x\\
cx+dy+t_y\\
1
\end{bmatrix}(point)
⎣⎡ac0bd0txty1⎦⎤∗⎣⎡xy1⎦⎤=⎣⎡ax+by+txcx+dy+ty1⎦⎤(point)
变换的组合与分解
对于任意多个变换可以表示成一个矩阵.试想对一个点或向量不断左乘变换矩阵,然后将变换矩阵结合就变成一个了:
(Scale∗……∗Rotation(ϕ))∗[xy1]=A∗[xy1]
(Scale*……*Rotation(\phi))*\begin{bmatrix}
x\\
y\\
1
\end{bmatrix} = A*\begin{bmatrix}
x\\
y\\
1
\end{bmatrix}
(Scale∗……∗Rotation(ϕ))∗⎣⎡xy1⎦⎤=A∗⎣⎡xy1⎦⎤
对于变换的顺序:从右往左进行变换。矩阵乘法没有交换律,因此不能随意交换变换顺序。
变换的分解:
eg:绕给定点旋转?
先平移到原点,再旋转,再进行平移。(转换成已有的变换)
3D空间中的变换
使用齐次坐标:
2D向量:(x,y,z)T=>(x,y,z,0)T(x,y,z)^T=>(x,y,z,0)^T(x,y,z)T=>(x,y,z,0)T
2D点 :(x,y,z)T=>(x,y,z,1)T(x,y,z)^T=>(x,y,z,1)^T(x,y,z)T=>(x,y,z,1)T
对于3D点 :(x,y,w)T=>(x/w,y/w)Tw!=0(x,y,w)^T=>(x/w,y/w)^Tw!=0(x,y,w)T=>(x/w,y/w)Tw!=0。
那么3D空间中的仿射变换为:
[abctxdeftyghitz0001]∗[xyz1]=[ax+by+cz+txdx+ey+fz+tygx+hy+iz+tz1](point)
\begin{bmatrix}
a & b & c&t_x\\
d & e & f &t_y\\
g & h & i& t_z\\
0&0&0&1
\end{bmatrix}*
\begin{bmatrix}
x\\
y\\
z\\
1
\end{bmatrix}=
\begin{bmatrix}
ax+by+cz+t_x\\
dx+ey+fz+t_y\\
gx+hy+iz+t_z\\
1
\end{bmatrix}(point)
⎣⎢⎢⎡adg0beh0cfi0txtytz1⎦⎥⎥⎤∗⎣⎢⎢⎡xyz1⎦⎥⎥⎤=⎣⎢⎢⎡ax+by+cz+txdx+ey+fz+tygx+hy+iz+tz1⎦⎥⎥⎤(point)
3D空间中变换与2D中的类似,但是旋转比较特殊,由此总结如下。
3D空间中的旋转
2D中的旋转表示为绕点旋转,而3D中的旋转表示为绕轴逆时针旋转。
绕x轴,y轴,z轴(坐标轴如下所示为右手坐标系):
Rx(ϕ)=[100tx0cosϕ−sinϕty0sinϕcosϕtz0001](绕x轴)Ry(ϕ)=[cosϕ0sinϕtx010ty−sinϕ0cosϕtz0001](绕y轴)Rz(ϕ)=[cosϕ−sinϕ0txsinϕcosϕ0ty001tz0001](绕z轴)
R_x(\phi)=\begin{bmatrix}
1 & 0 & 0&t_x\\
0 & \cos{\phi} & -\sin{\phi} &t_y\\
0 & \sin{\phi} & \cos{\phi}& t_z\\
0&0&0&1
\end{bmatrix}(绕x轴)\\
R_y(\phi)=\begin{bmatrix}
\cos{\phi} &0& \sin\phi&t_x\\
0 & 1 & 0& t_y\\
-\sin{\phi} & 0&\cos{\phi} &t_z\\
0&0&0&1
\end{bmatrix}(绕y轴)\\
R_z(\phi)=\begin{bmatrix}
\cos{\phi} & -\sin{\phi} &0&t_x\\
\sin{\phi} & \cos{\phi}&0& t_y\\
0 & 0 & 1&t_z\\
0&0&0&1
\end{bmatrix}(绕z轴)
Rx(ϕ)=⎣⎢⎢⎡10000cosϕsinϕ00−sinϕcosϕ0txtytz1⎦⎥⎥⎤(绕x轴)Ry(ϕ)=⎣⎢⎢⎡cosϕ0−sinϕ00100sinϕ0cosϕ0txtytz1⎦⎥⎥⎤(绕y轴)Rz(ϕ)=⎣⎢⎢⎡cosϕsinϕ00−sinϕcosϕ000010txtytz1⎦⎥⎥⎤(绕z轴)

对于绕任意轴的旋转,同样是可以转成绕x,y,z轴的旋转。
分解公式(Rodrigues’s Rotation Formula):
R(n,α)=cos(α)I+(1−cosα)nnT+sinα[0−nznynz0−nx−nynx0]
R(\pmb n,\alpha) =\cos(\alpha)\pmb I+(1-\cos \alpha)\pmb n\pmb n^T+\sin\pmb\alpha\begin{bmatrix}
0 & -\pmb n_z & \pmb n_y\\
\pmb n_z & 0 & -\pmb n_x\\
-\pmb n_y & \pmb n_x & 0\\
\end{bmatrix}
R(nnn,α)=cos(α)III+(1−cosα)nnnnnnT+sinααα⎣⎡0nnnz−nnny−nnnz0nnnxnnny−nnnx0⎦⎤
NOTE:默认n\pmb nnnn经过原点,对于轴来说需要指定起点,这里默认的起点为原点。如若遇到起点不在原点,可先平移到原点,在进行旋转,在平移回去。
四元数:主要是为了进行旋转的插值。
观测变换(view/camera transfrom)
介绍之前变换的目的是为了讨论虚拟相机的成像。给定一个3D场景,我们如何将其最终渲染到屏幕上(如何拍一张照片)。
- 站好位置(模型变换)
- 调好相机位置(视图变换,view/camera transfrom)
- 成像,拍照(投影变换,3维变2维,Projection (投影) transformation )
视图变换
如何定义相机的位置,与摆放?
- 位置。
- 朝向(看向的方向)
- 向上的方向。
通过这些可以确定一个相机。
为了方便起见。可以将相机变换到原点(位置),向上方向为y轴方向,看向z轴的负方向(朝向)。然后将所有其他物体进行同样的变换。
相机变换
为了将一个任意相机(位置,朝向,向上的方向分别为(e,g^,t^\pmb e,\hat g,\hat teee,g^,t^)变换到我们预想的位置。
- 将位置变换到原点e=>o\pmb e=>\pmb oeee=>ooo
- 将朝向变换到Z\pmb ZZZZ轴负方向g^=>−Z\hat g=>-\pmb Zg^=>−ZZZ
- 将向上方向变换到Y\pmb YYYY轴的正方向t^=>Y\hat t=>Yt^=>Y。
那么变换矩阵该怎么写呢?
- 平移2. 旋转
Mview=RviewTviewM_{view}=R_{view}T_{view}Mview=RviewTview
平移变换矩阵很好写:
Tview=[100−xe010−ye001−ze0001]
T_{view}=\begin{bmatrix}
1& 0 &0&-x_{\pmb e}\\
0 & 1&0& -y_{\pmb e}\\
0 & 0 & 1&-z_{\pmb e}\\
0&0&0&1
\end{bmatrix}
Tview=⎣⎢⎢⎡100001000010−xeee−yeee−zeee1⎦⎥⎥⎤
旋转的做法:
- 将g^=>−Z,t^=>Y,g^×t^=>X\hat g=>-\pmb Z,\hat t=>Y,\hat g \times \hat t=>Xg^=>−ZZZ,t^=>Y,g^×t^=>X(如下图所示)
对于旋转矩阵来说非常难写。但是从反向来(逆变换)看比较简单(旋转矩阵是正交矩阵,其对称矩阵便是它的逆矩阵)。
将X=>g^×t^,Y=>t^,−Z^=>g\pmb X=>\hat g \times \hat t,\pmb Y=>\hat t,-\hat Z=>\pmb gXXX=>g^×t^,YYY=>t^,−Z^=>ggg
Rview−1=[xg×txtx−g0yg×tyty−g0zg×tztz−g00001]Rview=[xg×tyg×tzg×t0xtytzt0x−gy−gz−g00001]
R_{view}^{-1}=\begin{bmatrix}
x_{g\times t}& x_t &x_{-g}&0\\
y_{g\times t} & y_t& y_{-g}&0\\
z_{g\times t} & z_t & z_{-g}&0\\
0&0&0&1
\end{bmatrix}\\
R_{view}=\begin{bmatrix}
x_{g\times t}& y_{g\times t} &z_{g\times t}&0\\
x_t & y_t&z_t& 0\\
x_{-g} & y_{-g}& z_{-g}&0\\
0&0&0&1
\end{bmatrix}
Rview−1=⎣⎢⎢⎡xg×tyg×tzg×t0xtytzt0x−gy−gz−g00001⎦⎥⎥⎤Rview=⎣⎢⎢⎡xg×txtx−g0yg×tyty−g0zg×tztz−g00001⎦⎥⎥⎤

对于view/camera transfrom,观测变换,由于相机与模型的相对位置关系,也叫做ModelView Transform。
投影变换
关于正交投影与透视投影的区别如下图。

透视投影符合近大远小的规律。
正交投影
定义一个空间的立方体([l,r]×[b,t]×[f,n][l, r] \times [b, t] \times [f, n][l,r]×[b,t]×[f,n]),(分别表示在x,y,z轴上的范围)。
把其映射到标准立方体(中心在原点,大小[−1,1]3[-1,1]^3[−1,1]3),由于看向z轴的负方向,那么离相机越近,z值越大,越远越小。
则其变换矩阵:
首先平移中心,后缩放。则有:
Mproject=[2/(r−l)00002/(t−b)00002/(n−f)00001][100−(l+r)/2010−(b+t)/2001−(f+n)/20001]=[2(r−l)00−r+lr−l02(r−b)0−t+bt−b002(n−f)−n+fn−f0001]
M_{project}=\left[ \begin{matrix}
2/(r-l) & 0 & 0 & 0\\
0 & 2/(t-b) & 0 & 0 \\
0 & 0 & 2/(n-f) & 0\\
0 & 0 & 0 & 1\end{matrix}\right]
\left[ \begin{matrix}
1 & 0 & 0 & -(l+r)/2\\
0 & 1 & 0 & -(b+t)/2 \\
0 & 0 & 1 & -(f+n)/2\\
0 & 0 & 0 & 1\end{matrix}
\right]\\
=\left[ \begin{matrix}
\frac{2}{(r-l)} & 0 & 0 & -\frac{r+l}{r-l}\\
0 & \frac{2}{(r-b)} & 0 & -\frac{t+b}{t-b} \\
0 & 0 & \frac{2}{(n-f)} & -\frac{n+f}{n-f}\\
0 & 0 & 0 & 1\end{matrix}\right]
Mproject=⎣⎢⎢⎡2/(r−l)00002/(t−b)00002/(n−f)00001⎦⎥⎥⎤⎣⎢⎢⎡100001000010−(l+r)/2−(b+t)/2−(f+n)/21⎦⎥⎥⎤=⎣⎢⎢⎢⎡(r−l)20000(r−b)20000(n−f)20−r−lr+l−t−bt+b−n−fn+f1⎦⎥⎥⎥⎤
物体确实会被拉伸(后续会做视口变换)。
透视投影
- 近大远小
- 平行线不再平行
如图所示为了更好的得到变换矩阵,可以先压缩放,经四棱台压缩成立方体,后利用正交投影来做。
- 近平面不变。
- z值不变。
- 任意切面上的中心点位置不变。

基于几个假设来推导透视投影的矩阵。
近平面上的点映射到立方体上,坐标不变。
远平面上的点映射到立方体上,z值不变,中心点坐标不变。
透视投影的矩阵推导
压缩
利用相似三角形,如图所示,对于一个初始点(x,y,z)(x,y,z)(x,y,z)将其映射到立方体上。有如下相似三角形。
则变换后的y′=nzyy^{'}=\frac{n}zyy′=zny。同理x′=nzxx^{'}=\frac{n}zxx′=znx。
那么对于任意(x,y,z)(x,y,z)(x,y,z)在其次坐标下有:
[xyz1]=>[x′y′unkown1]=[nzxnzyunkown1]=[nxnyunkownz]齐次坐标下的点
\left[ \begin{matrix}
x\\
y \\
z \\
1 \end{matrix}\right]
=>\left[ \begin{matrix}
x^{'}\\
y^{'} \\
\text{unkown} \\
1 \end{matrix}\right]=
\left[ \begin{matrix}
\frac{n}zx\\
\frac{n}zy \\
\text{unkown} \\
1 \end{matrix}\right]=
\left[ \begin{matrix}
nx\\
ny \\
\text{unkown} \\
z \end{matrix}\right]\text{齐次坐标下的点}
⎣⎢⎢⎡xyz1⎦⎥⎥⎤=>⎣⎢⎢⎡x′y′unkown1⎦⎥⎥⎤=⎣⎢⎢⎡znxznyunkown1⎦⎥⎥⎤=⎣⎢⎢⎡nxnyunkownz⎦⎥⎥⎤齐次坐标下的点
那么可以得到构造矩阵:
[n0000n00????0010]∗[xyz1]=[nxnyunkownz]
\left[ \begin{matrix}
n & 0 & 0 & 0\\
0 & n & 0 & 0\\
? & ? & ? & ?\\
0 & 0 & 1 & 0\end{matrix}
\right]*\left[ \begin{matrix}
x\\
y \\
z \\
1 \end{matrix}\right]=
\left[ \begin{matrix}
nx\\
ny \\
\text{unkown} \\
z \end{matrix}\right]
⎣⎢⎢⎡n0?00n?000?100?0⎦⎥⎥⎤∗⎣⎢⎢⎡xyz1⎦⎥⎥⎤=⎣⎢⎢⎡nxnyunkownz⎦⎥⎥⎤
为了得到第三行的元素:利用之前的假设
近平面上的点映射到立方体上,坐标不变。
远平面上的点映射到立方体上,z值不变,中心点坐标不变。
则有:
[n0000n00ABCD0010]∗[x′y′n1]=[nx′ny′n2n]==[x′y′n1][n0000n00ABCD0010]∗[centerxcenteryf1]=[f∗centerxf∗centeryf2f]Ax+By+Cn+D=n2A∗centerx+B∗centery+Cf+D=f
\left[ \begin{matrix}
n & 0 & 0 & 0\\
0 & n & 0 & 0\\
A & B & C & D\\
0 & 0 & 1 & 0\end{matrix}
\right]*\left[ \begin{matrix}
x^{'}\\
y^{'} \\
n \\
1 \end{matrix}\right]=
\left[ \begin{matrix}
nx^{'}\\
ny^{'} \\
n^2 \\
n \end{matrix}\right]==
\left[ \begin{matrix}
x^{'}\\
y^{'} \\
n \\
1 \end{matrix}\right]\\
\left[ \begin{matrix}
n & 0 & 0 & 0\\
0 & n & 0 & 0\\
A & B & C & D\\
0 & 0 & 1 & 0\end{matrix}
\right]*\left[ \begin{matrix}
center_x\\
center_y \\
f \\
1 \end{matrix}\right]=
\left[ \begin{matrix}
f*center_x\\
f*center_y\\
f^2 \\
f \end{matrix}\right]\\
Ax+By+Cn+D = n^2\\
A*center_x+B*center_y+Cf+D =f
⎣⎢⎢⎡n0A00nB000C100D0⎦⎥⎥⎤∗⎣⎢⎢⎡x′y′n1⎦⎥⎥⎤=⎣⎢⎢⎡nx′ny′n2n⎦⎥⎥⎤==⎣⎢⎢⎡x′y′n1⎦⎥⎥⎤⎣⎢⎢⎡n0A00nB000C100D0⎦⎥⎥⎤∗⎣⎢⎢⎡centerxcenteryf1⎦⎥⎥⎤=⎣⎢⎢⎡f∗centerxf∗centeryf2f⎦⎥⎥⎤Ax+By+Cn+D=n2A∗centerx+B∗centery+Cf+D=f
对于任意近平面的任意(x,y)都有Ax+By+Cn+D=nAx+By+Cn+D = nAx+By+Cn+D=n,因此A=0,B=0A=0,B=0A=0,B=0.
因此联立Cn+D=n2,Cf+D=f2Cn+D=n^2,Cf+D=f^2Cn+D=n2,Cf+D=f2
则可以解得:C=n+f,D=−nfC=n+f,D=-nfC=n+f,D=−nf
因此可以得到
Mpresp−>ortho=[n0000n0000n+f−nf0010]Mpresp=MorthoMpresp−>ortho
M_{presp->ortho}=\left[ \begin{matrix}
n & 0 & 0 & 0\\
0 & n & 0 & 0\\
0& 0 & n+f & -nf\\
0 & 0 & 1 & 0\end{matrix}
\right]\\
M_{presp}=M_{ortho}M_{presp->ortho}
Mpresp−>ortho=⎣⎢⎢⎡n0000n0000n+f100−nf0⎦⎥⎥⎤Mpresp=MorthoMpresp−>ortho
Reference
- https://www.bilibili.com/video/BV1X7411F744?t=4503&p=4
- https://sites.cs.ucsb.edu/~lingqi/teaching/games101.html
本文深入探讨图形学中的基本变换原理,包括2D和3D空间中的旋转、缩放、错切和平移等操作,详细讲解了齐次坐标、仿射变换、投影变换以及相机变换的概念与应用。
1159





