赞
踩
本学期中期的时候,出于个人兴趣,用unity自己做了两个小游戏:愤怒的小鸟和合成大西瓜。感觉非常有意思,完成度也还算可以,后续有空会分享一些制作过程和遇到的困难。在做那两个小游戏之前我是完全不了解整个游戏开发的流程的,也没有掌握相关的知识。感觉学校教的一些东西不太相关?由于个人还是想要向游戏行业发展(网安太难了感觉提不起兴趣来),所以觉得有必要来系统地学习一下在国内游戏领域应用十分广泛的计算机图形学(computer graphics)。
我是看的《Fundamentals of Computer Graphics》这本书,俗称虎书。在b站上看的闫令琪老师的课。
变换矩阵是数学线性代数中的一个概念。在线性代数中,线性变换能够用矩阵表示。如果 T T T是一个把 R n R_n Rn映射到 R m R_m Rm的线性变换,且 x x x是一个具有 n n n个元素的列向量 ,那么我们把 m × n m×n m×n的矩阵 A A A,称为 T T T的变换矩阵。
这是百科对变换矩阵的解释。而在图形学中,变换矩阵的作用十分之大,一切物体的缩放,旋转,位移等操作都可以通过变换矩阵作用得到。本文将会介绍一些常用的变换矩阵。
学习之前我们需要掌握一些线性代数的知识,学过这门课的应该都感觉不难,是最基础的一些知识。遥想当年我线代期末考了满分
向量加减
点乘积、叉乘积、右手螺旋定则
矩阵乘法
既然由上边的定义了解到变换矩阵是通过乘法来体现的,我们就先来复习一下简单的矩阵乘法,接下来的运算都是此基础上的变式。在此式中
[
a
1
a
2
a
3
a
4
]
[
a
1
a
2
a
3
a
4
]
[
x
y
]
=
[
a
1
x
+
a
2
y
a
3
x
+
a
4
y
]
缩放就是将物体沿着坐标轴进行压缩或拉伸的操作,它的变换矩阵定义如下
s
c
a
l
e
(
s
x
,
s
y
)
=
[
s
x
0
0
s
y
]
scale(s_x,s_y)=
[
s
x
0
0
s
y
]
[
x
y
]
=
[
s
x
x
s
y
y
]
切变直观理解就是把物体一边固定,然后拉另外一边。定义以及解释可能都有点抽象,结合图来分析:
先不用管图中的变换矩阵,根据前面缩放的经验,我们只需找出点与点之间的数量关系即可。由图中可以看出,此变换在
y
y
y轴上并没有做出任何改动,是
x
x
x轴有向右拉伸的意思。再细看发现底端
y
=
0
y=0
y=0这条也没有经过任何变换,看最上端这条直线变化最大(我们假设此时
y
=
1
y=1
y=1,并向右移动了距离
a
a
a),而原本位于
(
0
,
1
)
(0,1)
(0,1)的这个点,变为了
(
a
,
1
)
(a,1)
(a,1)。再看看中点呢?不难发现,原本位于
(
0
,
1
2
)
(0,\frac{1}{2})
(0,21)的这个点,变为了
(
a
2
,
1
2
)
(\frac{a}{2},\frac{1}{2})
(2a,21)。所以在此图中,可以得到其变换矩阵为:
s
h
e
a
r
=
[
1
a
0
1
]
shear=
[
1
a
0
1
]
[
x
y
]
=
[
x
+
a
y
y
]
s
h
e
a
r
−
x
(
s
)
=
[
1
s
0
1
]
s
h
e
a
r
−
y
(
s
)
=
[
1
0
s
1
]
shear-x(s)=
这个就没啥好说的了,就是镜面对称的意思。它的变换矩阵定义如下
r
e
f
l
e
c
t
−
x
=
[
1
0
0
−
1
]
r
e
f
l
e
c
t
−
y
=
[
−
1
0
0
1
]
reflect-x=
[
1
0
0
−
1
]
[
x
y
]
=
[
x
−
y
]
旋转就是物体的转动了,先看一下它的变换矩阵
r
o
t
a
t
e
(
ϕ
)
=
[
c
o
s
ϕ
−
s
i
n
ϕ
s
i
n
ϕ
c
o
s
ϕ
]
rotate(\phi)=应该还是挺清晰易懂的吧
所以,原来的矩阵与它相乘后变成了这样
[
c
o
s
ϕ
−
s
i
n
ϕ
s
i
n
ϕ
c
o
s
ϕ
]
[
x
y
]
=
[
x
c
o
s
ϕ
−
y
s
i
n
ϕ
x
s
i
n
ϕ
+
y
c
o
s
ϕ
]
补充:由上述可以得到
r
o
t
a
t
e
(
−
ϕ
)
=
[
c
o
s
ϕ
s
i
n
ϕ
−
s
i
n
ϕ
c
o
s
ϕ
]
rotate(-\phi)=
对于一下的举例以及分析,都是针对二维变换。理解之后三维变换也就水到渠成,有类似特征。
我们都希望所有的物体位置变换都能够通过变换矩阵与向量的乘积一次性得到,但是偏偏有这个异类,就是平移。
如上图,我们想要将图片右移
t
x
t_x
tx上移
t
y
t_y
ty,可得有方程组
{
x
′
=
x
+
t
x
y
′
=
y
+
t
y
[
x
′
y
′
]
=
[
a
b
c
d
]
[
x
y
]
+
[
t
x
t
y
]
齐次坐标就是将一个原本是 n n n维的向量用一个 n + 1 n+1 n+1维向量来表示,是指一个用于投影几何里的坐标系统,如同用于欧氏几何里的笛卡儿坐标一般。关于它的重要性:
《计算机图形学(OpenGL版)》的作者F.S. Hill Jr.曾说过一句话:
“齐次坐标表示是计算机图形学的重要手段之一,它既能够用来明确区分向量和点,同时也更易用于进行仿射(线性)几何变换。”
于是我们知道,其重要性,主要有二,其一是区分向量和点,其二是易于进行仿射变化(Affine Transformation) 。
具体怎么应用呢?可以浅显的理解为:对于点来说,扩展为 ( x , y , 1 ) T (x,y,1)^T (x,y,1)T。对向量来说,扩展为 ( x , y , 0 ) T (x,y,0)^T (x,y,0)T
对于平移来说,就可以这样表示:
[
x
′
y
′
1
]
=
[
1
0
t
x
0
1
t
y
0
0
1
]
[
x
y
1
]
=
[
x
+
t
x
y
+
t
y
1
]
[
1
0
t
x
0
1
t
y
0
0
1
]
[
x
y
1
]
这是针对每个点的平移来说的,那么为什么向量要拓展为
(
x
,
y
,
0
)
T
(x,y,0)^T
(x,y,0)T,最后是一个零呢?
[
x
′
y
′
0
]
=
[
1
0
t
x
0
1
t
y
0
0
1
]
[
x
y
0
]
=
[
x
y
0
]
再看上面那个名人名言中的:齐次坐标有利于进行仿射变换。那么仿射变换又是什么呢?
个人理解仿射变换其实是就是上述两种简单变换的叠加:一个是线性变换,一个是平移变换
仿射变换变化包括缩放、旋转、反射、错切以及平移,原来的直线仿射变换后还是直线,原来的平行线经过仿射变换之后还是平行线,这就是仿射。就是我们上述介绍的变换的组合。当然也就是我们介绍齐次坐标所用到的矩阵变化。
一个集合的仿射变换为:
f
(
x
)
=
A
x
+
b
,
x
∈
X
f(x)=Ax+b,x\in X
f(x)=Ax+b,x∈X仿射变换是二维平面中一种重要的变换,在图像图形领域有广泛的应用,在二维图像变换中,一般表达为:
[
x
′
y
′
1
]
=
[
R
0
R
1
t
x
R
2
R
3
t
y
0
0
1
]
[
x
y
1
]
据此可以得出引入齐次坐标后仿射变化的变换矩阵了,对于平移:
M
=
[
1
0
t
x
0
1
t
y
0
0
1
]
M=
同理,对于线性变换的四种,由于没有平移量,故
t
x
t_x
tx,
t
y
t_y
ty都为0,所以它们的变换矩阵:
M
=
[
A
B
0
C
D
0
0
0
1
]
M=
变换的组合其实就是上述线性与平移变换的叠加变换。需要注意的是变换的顺序:先线性后平移。
看下面一个例子,如果进行图示的变换呢?
第一种方案是先平移后旋转,显然是不行的。
先旋转后平移是可以的。
为什么一定要保持这个顺序呢?因为矩阵乘法没有交换律!
而针对数学表达来说,我个人形象的理解为遵循就近原则,向量先与最接近的变换矩阵相乘。
分解其实就是组合的逆过程,一种简单的方法是:先将左下点移动到原点之后再进行线性与平移操作。
3D变换跟上述的2D变化大多拥有相同的规律,无论是考不考虑齐次坐标,也就相当于多增加了一个维度。
仿射变换在三维当中的应用表达式为:
[
x
′
y
′
z
′
1
]
=
[
R
0
R
1
R
2
t
x
R
3
R
4
R
5
t
y
R
6
R
7
R
8
t
z
0
0
0
1
]
[
x
y
z
1
]
3D变换的平移用齐次坐标表示的变换矩阵为:
t
r
a
n
s
l
a
t
i
o
n
(
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
]
translation(t_x,t_y,t_z)=
3D变换的缩放用齐次坐标表示的变换矩阵为:
s
c
a
l
e
(
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
]
scale(s_x,s_y,s_z)=
3D当中的旋转可以说是最难的一种物体变换,和2D有很大的不同。首先考虑最简单的绕三个轴旋转,变换矩阵依次为:
R
x
(
α
)
=
[
1
0
0
0
0
c
o
s
α
−
s
i
n
α
0
0
s
i
n
α
c
o
s
α
0
0
0
0
1
]
R
y
(
α
)
=
[
c
o
s
α
0
s
i
n
α
0
0
1
0
0
−
s
i
n
α
0
c
o
s
α
0
0
0
0
1
]
R
z
(
α
)
=
[
c
o
s
α
−
s
i
n
α
0
0
s
i
n
α
c
o
s
α
0
0
0
0
1
0
0
0
0
1
]
R_x(\alpha)=
因此理解了上面这个来看绕 x x x(绕 x x x轴,故 x x x不变,且 y y y转向 z z z)和 z z z(绕 z z z轴,故 z z z不变,且 x x x转向 y y y)旋转的变换矩阵。那绕 y y y轴为啥会有所不同呢?主要原因是我们是固定 y y y轴,然后由且 z z z转向 x x x,而不是 x x x转向 z z z,故有所不同。
同上述2D,3D变换中的旋转矩阵也都是正交矩阵
之前2D中变换的分解我们可以了解到这么一个思想:先把物体平移到原点,再进行线性变化,之后将物体平移回去。在3D旋转中我们同样可以借鉴这个思想,我们可以先将物体整个平移到相较于它的坐标轴零点,然后进行相应的旋转,之后再把物体平移回去即可。
内容已同步更新至lbw的小窝,不过上面的矩阵全都表示不出来啊啊啊,我用typora写的在上面好好的,挂到csdn上显示不出来还另外改了格式,然后在个人博客上还是显示不出来,算了累了就这样吧…
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。