Skip to content

GAMES101 学习笔记03:变换

两类变换

  • Modeling
  • Viewing

2D 变换

线性变换 = 矩阵 同维矩阵

[xy]=[abcd][xy]x=Mx

缩放矩阵(Scal Matrix)

[xy]=[sx00sy][xy]

反射矩阵(Reflection Matrix)

[xy]=[1001][xy]

剪切矩阵(Shear Matrix)

[xy]=[1a01][xy]

旋转矩阵(Rotation Matrix)关于原点,默认逆时针

[xy]=[cosθsinθsinθcosθ][xy]Rθ=[cosθsinθsinθcosθ]

TIP

对于顺时针旋转:

Rθ=[cosθsinθsinθcosθ]

不难看出:

Rθ=RθT=Rθ1

Rθ是一个正交矩阵,

齐次坐标与平移变换(Homogeneous coordinates and Translation)

平移变换(Translation)

[xy]=[1001][xy]+[txty]

与上述所有变换不同,所以平移变换不是线性变换。

齐次坐标(Homogeneous coordinates)

作为一个解决办法,统一所有变换。

通过增加一维(w):

2Dpoint=(x,y,1)T2Dvector=(x,y,0)T

INFO

向量中增加的0是对向量的一种「保护」,确保平移变换后向量本身没有改变。

vector+vector=vectorpointpoint=vectorpoint+vector=point

对于:

point+point

在齐次坐标系下:

[xyw]T

是 2D 点:

[x/wy/w1]T

即两个点的中点。

平移的矩阵表示:

[xyw]=[10tx01ty001][xy1]=[x+txy+ty1]

仿射变换(Affine Transformations)

上述变换的总称

所有的仿射变换:

[xy]=[abcd][xy]+[txty]

都可以写成齐次坐标的形式:

[xy1]=[abtxcdty001][xy1]

用一个矩阵统一了所有变换

INFO

注意,这里是先应用线性变换,再进行平移。3D 下同理。

INFO

缩放:

S(sx,sy)=[sx000sy0001]

旋转:

R(α)=[cosαsinα0sinαcosα0001]

平移:

T(tx,ty)=[10tx01ty001]

其他变换

逆变换(Inverse Transform)

组合变换(Composing Transforms)

组合变换的顺序很重要!因为矩阵乘法不能交换。

WARNING

注意矩阵是从右到左应用的:

T(tx,ty)R(α)[xy1]=[sx000sy0001][cosαsinα0sinαcosα0001][xy1]

虽然矩阵乘法没有交换律,但是有结合律。这就意味着可以做预乘,得到一个矩阵后再变换,优化性能。

分解复杂变换

如何围绕任意定点c旋转?

  1. c平移至原点
  2. 旋转
  3. c平移回去

T(c)R(α)T(c)

3D 变换

3Dpoint=(x,y,z,1)T3Dvector=(x,y,z,0)T

同样:

(x,y,z,w)T

也就是 3D 点:

(x/w,y/w,z/w,1)T

3D 仿射变换

[xyz1]=[abctxdeftyghitz0001][xyz1]

INFO

与 2D 仿射变换相同,是先应用线性变换,再进行平移。

INFO

缩放:

S(sx,sy,sz)=[10000cosθsinθ00sinθcosθ00001]

平移:

T(tx,ty,tz)=[100tx010ty001tz0001]

3D 旋转变换

旋转(关于x,y,z)是 3D 仿射变换中的一个难点:

Rx(α)=[10000cosθsinθ00sinθcosθ00001]Ry(α)=[cosθ0sinθ00100sinθ0cosθ00001]Rz(α)=[cosθsinθ00sinθcosθ0000100001]Rxyz(α,β,γ)=Rx(α)Ry(α)Rz(α)

(α,β,γ)被称为欧拉角。

INFO

有关围绕y旋转,sinθ的位置略有不同。事实上,这和三位向量叉乘的循环对称性有关。

  • x×y=z

  • y×z=x

  • z×x=y

    • (x×z=y)
Rodrigues’ Rotation 公式

将围绕任意轴n旋转α进行分解,得到围绕x,y,z旋转的矩阵N

R(n,α)=cos(α)I+(1cos(α))nnT+sin(α)[0nznynz0nxnynx0]N=[0nznynz0nxnynx0]

默认轴n过原点。

INFO

此处的矩阵n实际上就是叉乘中提到的:笛卡尔坐标系下向量的叉乘中使用的矩阵。

观测变换(Viewing transformation)

视图/摄像机变换(View/Camera transformation)

定义一个摄像机:

  • 位置(Position)e
  • 目光方向(Gaze direction)g^
  • 向上方向(Up direction)t^

当相机与物体一同运动(没有相对运动),「相片」是相同的:

因此,我们总是把相机放在原点(向上方向为 y,目光方向为 -z),并随着相机变换物体:

对于一个位于(e,t^,g^)的相机,我们使用 Mview 将其变换至原点:

  1.  e 移动到原点
  2.  g^ 旋转到 -z
  3.  t^ 旋转到 y
  4.  g^×t^ 旋转到 x

对于一个矩阵 Mview

Mview=RviewTview

WARNING

因为齐次坐标是「先线性变换,再平移变换」,与我们所需要的效果相反,所以此处将 Mview 拆分成了两个矩阵,其中负责平移的 Tview 在最右侧,最先生效。

其中 Tview  e 移动到原点:

Tview=[100xe010ye001ze0001]

 Rview 完成相应的旋转变换:

INFO

  •  g^ 旋转到 -z
  •  t^ 旋转到 y
  •  g^×t^ 旋转到 x
Rview=[xg^×t^yg^×t^zg^×t^0xtytzt0xgygzg00001]

TIP

将轴旋转到(x,y,z)比较抽象,不妨反过来思考。对于逆旋转变换:

Rview1=[xg^×t^xtxg0yg^×t^ytyg0zg^×t^ztzg00001]

进而可以得到 Rview

视图/摄像机变换也被成为模型视图(ModelView)变换,它将应用于后面提到的透视投影

投影变换(Projection transformation)

投影:3D 到 2D 的过程

正交投影(Orthographic projection)

一种简单的理解:

  • 摄像机位于原点,朝向 -z,向上方向为 y
  • 丢弃 z 坐标
  • 得到的图形平移缩放至矩形 [1,1]2

图形学上正式的做法:

  • 定义一个空间上的立方体 [l,r]×[b,t]×[f,n],将其映射到一个空间上的标准立方体 [1,1]3
  • 过程(与简单理解中丢弃 z 的做法不同):
    1. 平移到原点
    2. 缩放至标准立方体

变换矩阵:

受限平移到原点,然后缩放(长宽高为2)

Mortho=[2rl00002tb00002nf00001][100r+l2010t+b2001n+f20001]

TIP

  • 因为目光方向为 -z,所以近大于远(n > f)
    • 这是就是为什么类似 OpenGL 等图形 API 使用左手系的原因。

透视投影(Perspective projection)

TIP

回顾一下齐次坐标:

(x,y,z,1)

(kx,ky,kz,k)k0

表示的是同一个点,那么自然

(xz,yz,z2,z)z0

表示的也是同一个点。

透视投影过程:

  1. 将 Frustum 挤压成长方体(n->n, f->f, Mpersportho
  2. 进行正交投影

WARNING

这里与之前接触的图形学内容不太一样,闫老师的解读是将一个透视投影的空间挤压成立方体,然后进行正交投影,得到透视投影的 2D 图像。

找到一个变换关系:

这实际上是一个相似三角形

对于 x 和 y,皆有这一关系,在其次坐标下有:

[xyz1][nxznyzunknown1]=z=[nxnystill unknownz]

因此,我们可以找到这个变换矩阵的一部分:

Mpersportho=[n0000n00????0010]

INFO

对于第三行的确定,我们可以立下几点规定:

  • 近平面上的点永远不变
  • 远平面上的点 z 值不变
  • 远平面中心点位置不变

因此对于近平面,用 n 代替 z,可以得到:

[xyn1][xyn1]=z(n)=[nxnyn2n]

因此我们知道 Mpersportho 的第三行必须是(0,0,A,B)的形式,即:

[00AB][xyn1]=n2

n2  x,y 无关。

但这还不够,我们还要考虑远平面。远平面中心点永远不变,因此有:

[00f1][00f1]==[00f2f]

同样可以知道 Mpersportho 的第三行必须是(0,0,A,B)的形式,即:

[00AB][00f1]=f2

于是得到方程组:

[n1f1][AB]=[n2f2]

解出结果:

A=n+fB=nf

至此,得到:

Mpersportho=[n0000n0000n+fnf0010]

接下来只需要再进行正交投影即可,即:

Mpersp=MorthoMpersportho
近平面的定义
  • 明确指定宽高
  • 给定垂直视野和纵横比(对于对称的情况:l=r, b=t

纵横比到 l,r,b,t 的转换:

tanfovY2=t|n|aspect=rt