1913 字
10 分钟
【CG】Games101-03学习笔记 & 作业解析

Transform#

为什么要学习 Transformation#

  1. 变换 (Transform) 的第一个应用场景就是移动,通过变换操作可以将空间中的物体移动(Translate)到你想要的位置。如视频中的相机的移动。

  2. 变换的第二个应用场景就是旋转,通过变换操作可以将空间中的物体进行旋转(Rotate)。如视频中的机器人的手臂进行旋转。

  3. 变换的第三个应用场景就是缩放,通过变换操作可以将空间中的物体进行缩放(Scale)。如视频中的字母 I 发生的形变。

  4. 变换还有一个非常重要的应用场景,就是在光栅化的成像中使用的投影变换,我们真实世界的物体是3维的,但是通过摄像机拍摄后得到的图片是二维的,我们将3维物体到2维图片的这么一个过程叫做投影变换(Projection)

2D Transformations#

Scale Matrix#

缩放变换 经过上图的变换操作,我们将原图形中某个点(x,y)(x,y),我们将其x轴缩放到原来的sxs_x倍,将其x轴缩放到原来的sys_y倍得到了新的点(x′,y′)(x',y'),相当于我们进行了如下的数学操作,

x′=sxx,y′=syyx' = s_x x,y' = s_y y[x′y′]=[sx00sy][xy]\begin{bmatrix} x' \\ y' \end{bmatrix}=\begin{bmatrix} s_x & 0\\ 0 &s_y \end{bmatrix}\begin{bmatrix} x\\ y \end{bmatrix}

其中矩阵运算中等号右边的第一项就是我们的缩放矩阵(scale matrix), 实际上这是一种线性变换(至于线性变换是什么,期待我的高等代数文章吧!)

Reflection Matrix#

对称变换或者叫反射变换可以将图形镜像翻转 上图我们将原图中的某个点(x,y)(x,y)对y轴进行对称变换得到了新的点(x′,y′)(x',y'),相当于我们进行了如下的数学操作,

x′=x,y′=−yx' = x,y' = -y[x′y′]=[−1001][xy]\begin{bmatrix} x' \\ y' \end{bmatrix}=\begin{bmatrix} -1 & 0\\ 0 &1 \end{bmatrix}\begin{bmatrix} x\\ y \end{bmatrix}

Shear Matrix#

剪切变换 对于变换后的点它的竖直方向的左边没有发生变换,只有水平方向上的坐标发生了变换,并且当y = 0的时候水平左边也没有发生变换,所以我们知道x的变换和y有关,并且通过变换后图像中的虚线的关系我们还知道x变换和a也有关,我们可以很轻松的得到变换后图像左上角的点的坐标是(a,1)变换前的左上角的坐标是(0,1)所以我们可以推断x′=ax+yx' = ax + y,也就是

[x′y′]=[1a01][xy]\begin{bmatrix} x' \\ y' \end{bmatrix}=\begin{bmatrix} 1 & a\\ 0 &1 \end{bmatrix}\begin{bmatrix} x\\ y \end{bmatrix}

Rotate Matrix#

旋转变换默认是绕着原点进行旋转的,也就是将原点定死,其他的点绕着原点进行旋转,并且默认是逆时针方向旋转 通过上图上的点的变换与三角函数的关系我们可以得到旋转操作是(至于怎么推导的还是期待我的数学专题吧)

[x′y′]=[cos⁡θ−sin⁡θsin⁡θcos⁡θ][xy]\begin{bmatrix} x' \\ y' \end{bmatrix}=\begin{bmatrix} \cos\theta & -\sin\theta\\ \sin\theta &\cos\theta \end{bmatrix}\begin{bmatrix} x\\ y \end{bmatrix}

Translation#

这个变换我们想写成数学的式子非常简单

x′=x+tx,y′=y+tyx' = x + t_x,y' = y + t_y

但是这不能写成一个矩阵乘以一个向量的形式了,我们只能写成

[x′y′]=[abcd][xy]+[txty]\begin{bmatrix} x' \\ y' \end{bmatrix}=\begin{bmatrix} a & b\\ c &d \end{bmatrix}\begin{bmatrix} x\\ y \end{bmatrix}+\begin{bmatrix} t_x\\ t_y \end{bmatrix}

所以为了解决这个问题,我们引入了齐次坐标

齐次坐标#

齐次坐标简单来说是将 nn 维向量用 n+1n+1 维坐标来表示的一种数学方式,这样做的好处是方便我们进行平移操作。 在笛卡尔坐标系下,旋转和缩放操作都可以使用矩阵乘进行操作,而平移只能通过加法操作,但是我们希望只通过矩阵乘法表示这些操作,这就需要引入齐次坐标,在齐次坐标中平移也可以写成矩阵乘法的形式。这样,所有的变换都能统一成矩阵乘法,从而方便GPU进行大规模并行计算。

将一个笛卡尔坐标转为齐次坐标:

(x,y)→(x,y,1)(x, y) \rightarrow (x, y, 1)

将一个齐次坐标转为笛卡尔坐标

(x,y,w)→(xw,yw)(x, y, w) \rightarrow \left(\frac{x}{w}, \frac{y}{w}\right)

而在齐次坐标下进行的变换我们称作仿射变换

平移操作#

在齐次坐标下(1,2,1)(1, 2, 1)、(2,4,2)(2, 4, 2) 和 (5,10,5)(5, 10, 5) 都表示笛卡尔空间中的同一个点 (1,2)(1, 2)。
通过这个方式我们可以将平移操作写成矩阵乘法,如下: 假设我们要将点在 xx 轴平移 txt_x,在 yy 轴平移 tyt_y,平移矩阵 T\mathbf{T} 如下:

T=[10tx01ty001]\mathbf{T} = \begin{bmatrix} 1 & 0 & t_x \\ 0 & 1 & t_y \\ 0 & 0 & 1 \end{bmatrix}

计算过程

[10tx01ty001][xy1]=[x+txy+ty1]\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}

同理

旋转操作#

假设我们要将点绕原点逆时针旋转角度 θ\theta,旋转矩阵 R\mathbf{R} 在齐次坐标下表示为:

R=[cos⁡θ−sin⁡θ0sin⁡θcos⁡θ0001]\mathbf{R} = \begin{bmatrix} \cos\theta & -\sin\theta & 0 \\ \sin\theta & \cos\theta & 0 \\ 0 & 0 & 1 \end{bmatrix}

计算过程:

[cos⁡θ−sin⁡θ0sin⁡θcos⁡θ0001][xy1]=[xcos⁡θ−ysin⁡θxsin⁡θ+ycos⁡θ1]\begin{bmatrix} \cos\theta & -\sin\theta & 0 \\ \sin\theta & \cos\theta & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} = \begin{bmatrix} x\cos\theta - y\sin\theta \\ x\sin\theta + y\cos\theta \\ 1 \end{bmatrix}

缩放操作#

虽然作业中没要求,但这里还是介绍一下, 将一个点(x,y,1)T(x,y,1)^T在 xx 轴方向缩放 sxs_x 倍,在 yy 轴方向缩放 sys_y 倍

S=[sx000sy0001]\mathbf{S} = \begin{bmatrix} s_x & 0 & 0 \\ 0 & s_y & 0 \\ 0 & 0 & 1 \end{bmatrix}

计算过程:

[sx000sy0001][xy1]=[sx⋅xsy⋅y1]\begin{bmatrix} s_x & 0 & 0 \\ 0 & s_y & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} = \begin{bmatrix} s_x \cdot x \\ s_y \cdot y \\ 1 \end{bmatrix}

齐次坐标下的点和向量#

  • 在齐次坐标下,点通常表示为 (x,y,1)T(x, y, 1)^T
  • 向量通常表示为 (x,y,0)T(x, y, 0)^T。 它们在齐次坐标下有如下的关系: 而 point + point 表示的是一个点 (x/w,y/w,1)(x/w, y/w, 1) 表示的是这两个点的中点

注意通常我们进行矩阵与向量相乘的时候,通常我们使用矩阵乘以一个向量,而不是向量乘以一个矩阵,所以如果我们进行这么一个操作 A×B×C×v⃗A \times B \times C \times \vec{v}那么对向量的操作是从右项左进行的,先对 v⃗\vec{v} 进行 CC 操作再是 BB 操作 AA 操作,这是因为矩阵乘法不满足交换律,先进行A和先进行B的操作是完全不同的。

我们的旋转只能绕着原点进行旋转,如果我们想绕着其他的点旋转我们应该怎么做呢?我们可以先将需要绕着旋转的点平移到原点(对物体整个进行平移,让这个点与原点进行重合),再进行旋转,最后再平移到原来的位置就行了 、

3D Transformations#

3维变换和2维变换一样,只是3维变换的矩阵会多一个维度,我们直接类比过去就行了,增加一个z轴 对于这个图中的变换矩阵,我们是先进行左上角3*3的变换最后再进行平移操作的,这是因为仿射变换直接对应了这么一个操作(拿2维举例子)

[x′y′]=[abcd][xy]+[txty]\begin{bmatrix} x' \\ y' \end{bmatrix}=\begin{bmatrix} a & b\\ c &d \end{bmatrix}\begin{bmatrix} x\\ y \end{bmatrix}+\begin{bmatrix} t_x\\ t_y \end{bmatrix}

而这个操作是先做线性变换再做平移的

作业解析#

不好意思,搞错了,这节的作业我们在上一节中做完了,所以作业解析在上一节的最后,这里就没作业了。

Games101

已完结

第 3 篇,共 14 篇本文属于系列

【CG】Games101-03学习笔记 & 作业解析
https://blog.cglab.top/posts/games_series/games101_03/
作者
Artichoke
发布于
2026-03-25
许可协议
CC BY-NC-SA 4.0

分享文章

生成精美分享图或复制链接,与更多人分享本文。

继续阅读

沿着主题读

基于共同的标签与分类

换条路线

从其他文章中稳定抽取

最后更新于 ,距今已过 213 天

部分内容可能已过时