Transform

为什么要学习 Transformation

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

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

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

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

2D Transformations

Scale Matrix

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

$$x' = s_x x,y' = s_y y$$

$$\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)$对y轴进行对称变换得到了新的点$(x',y')$,相当于我们进行了如下的数学操作,

$$x' = x,y' = -y$$

$$\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 + y$,也就是

$$\begin{bmatrix} x' \\ y' \end{bmatrix}=\begin{bmatrix} 1 & a\\ 0 &1 \end{bmatrix}\begin{bmatrix} x\\ y \end{bmatrix}$$

Rotate Matrix

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

$$\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 + t_x,y' = y + t_y$$

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

$$\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}$$

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

齐次坐标

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

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

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

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

$$(x, y, w) \rightarrow \left(\frac{x}{w}, \frac{y}{w}\right)$$

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

平移操作

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

$$\mathbf{T} = \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}$$

同理

旋转操作

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

$$\mathbf{R} = \begin{bmatrix} \cos\theta & -\sin\theta & 0 \\ \sin\theta & \cos\theta & 0 \\ 0 & 0 & 1 \end{bmatrix}$$

计算过程:

$$\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$ 轴方向缩放 $s_x$ 倍,在 $y$ 轴方向缩放 $s_y$ 倍

$$\mathbf{S} = \begin{bmatrix} s_x & 0 & 0 \\ 0 & s_y & 0 \\ 0 & 0 & 1 \end{bmatrix}$$

计算过程:

$$\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, 0)^T$。 它们在齐次坐标下有如下的关系: 而 point + point 表示的是一个点 $(x/w, y/w, 1)$ 表示的是这两个点的中点

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

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

3D Transformations

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

$$\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}$$

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

作业解析

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