- modeling(模型变换)
- translation(如游戏中视野的移动)
- rotation
- scaling
- viewing(视图变换,将三维投影到二维)
Scale
Scale Transform: x′=sx,y′=sy
Scale Matrix:
(x′y′)=(s00s)(xy)
Scale(Non-Uniform)
(x′y′)=(sx00sy)(xy)
Reflection
(x′y′)=(−1001)(xy)
Shear
(x′y′)=(10a1)(xy)
Rotate
(x′y′)=(cosθsinθ)x+(−sinθcosθ)y
⇒(x′y′)=(cosθsinθ−sinθcosθ)(xy)
(x′y′)=(acbd)(xy)⇒x′=Mx
Homogeneous coordinates
Translation
Why Homogeneous Coordinates
Translation cannot be represented in matrix form, translation is not linear transform.
(x′y′)=(acbd)(xy)+(txty)
But we don’t want translation to be a special case.
Solution: Homogenous Coordinates
Add a third coordinate (w-coordinate)
• 2D point = (x,y,1)T
• 2D vector = (x,y,0)T
根据 No free lunch theorem ,我们为了去除平移变换最后的一项,需要在其他地方增加一些复杂度。这里就是增加了一个维度。
Matrix representation of translations
x′y′w′=100010txty1⋅xy1=x+txy+ty1
对于一个点来说,经过平移矩阵变换会变成另一个点;但是对于一个向量来说,经过平移矩阵变换之后还是同一个向量。(保证向量平移不变性)
Valid operation if w-coordinate of result is 1 or 0
• vector + vector = vector
• point – point = vector
• point + vector = point
• point + point = ??
对于最后一个,扩充定义:
In homogeneous coordinates, xyw is the 2D point x/wy/w1(w=0)
那么最后的 point + point 就可以理解为求两点的中点。
Affine map = linear map + translation
(x′y′)=(acbd)(xy)+(txty)
Using homogenous coordinates:
x′y′w′=ac0bd0txty1⋅xy1
Scale
S(sx,sy)=sx000sy0001
Rotation
R(α)=cosαsinα0−sinαcosα0001
Translation:
S(sx,sy)=100010txty1
可以看出对于二维的仿射变换,矩阵的最后一行都是 0 0 1。如果不是的话,那么将对应其他的变换。
经过多次变换 ⇔ 左乘多个矩阵
根据矩阵的结合律,可以知道任意一个复杂的变换都可以用一个矩阵表示。(就是利用结合律将矩阵先乘起来)
同时由于矩阵之间没有交换律,可知如果将两个变换顺序互换,最终得到的结果一般不同。
Use homogeneous coordinates again:
• 3D point = (x,y,z,1)T
• 3D vector = (x,y,z,0)T
x′y′z′1=adg0beh0cfi0txtytz1⋅xyz1
The order: Linear Transform first(和二维中情形一样)
绕着 x,y,z 轴旋转
Rx(α)=10000cosαsinα00−sinαcosα00001
Ry(α)=cosα0−sinα00100sinα0cosα00001
Rz(α)=cosαsinα00−sinαcosα0000100001
可以看出绕 y 轴的旋转的矩阵和绕 x 轴、z 轴的有所不同,这个和右手螺旋定则有关。
3D Rotations
对于任意的旋转,可以看作是绕 x,y,z 轴旋转的叠加
Rxyz(α,β,γ)=Rx(α)Ry(β)Rz(γ)
这三个角度称为欧拉角。从直观上想象,如图
任意的旋转应该都是能被三个方向的旋转表示的
旋转的公式为
R(n,α)=cosα⋅I+(1−cosα)nnT+sinα0nz−ny−nz0nxny−nx0
表示以 n 方向为轴旋转 α 的角度。其中默认旋转轴经过原点。
把三维空间中的物体变成二维的图,就像拍照片。
- 首先找一个好的地方,把模型都放好(model transformation)
- 然后找一个好的角度、位置去放置相机(view transformation)
- 拍照,完成投影(projection transformation)
这里主要讲视图变换 (view transformation)
首先确定相机状态
- 位置(position) e
- 相机朝向(look-at / gaze direction) g^
- 相机顶部方向(up direction) t^,这是为了防止相机能绕着光轴旋转
考虑到一点:
如果相机和前景背景的相对位置不变,最后得到的结果是一样的。因此我们可以让相机处于一个标准位置上:为了方便,我们默认相机
- 处于原点
- 朝向 −z 方向
- 以 y 方向作为顶部
那么想要拍出合适的图,只要让其他物体跟着移动就行了。
如何将相机从一个任意位置移动到任意位置:
- 将 e 平移到原点
- 将 g^ 转到 −z 方向
- 将 t^ 转到 y 方向
- 将 g^×t^ 转到 x 方向
Mview=RviewTview。容易得到 Tview=100001000010−xe−ye−ze1
而对于矩阵 Rview,可以先考虑其逆矩阵,也就是将 x,y,z 分别转到 g^×t^,t^,−g^ 的矩阵。
Rview−1=xg^×t^yg^×t^zg^×t^0xt^yt^zt^0x−g^y−g^z−g^00001
考虑到旋转矩阵为正交矩阵,因此矩阵的逆等于矩阵转置
Rview=(Rview−1)−1=(Rview−1)T=xg^×t^xt^x−g^0yg^×t^yt^y−g^0zg^×t^zt^z−g^00001
- 正交投影(orthographic projection)(常用于工程制图)
- 透视投影(perspective projection)(常用于绘画,能展现近大远小的效果)
正交投影可以理解为将透视投影的camera的位置移到无穷远
Orthographic Projection
正交投影的一种简单理解是直接扔掉 z 轴坐标
而在图形学中,正交投影是将空间中的一个立方体 [l,r]×[b,t]×[f,n] 变换为一个“标准”(canonical)立方体 [−1,1]3。变换矩阵为
Mortho =r−l20000t−b20000n−f200001100001000010−2r+l−2t+b−2n+f1
Perspective Projection
透视投影是用的最广泛的一种投影,满足近大远小,同时带来的视觉效果为平行线不再平行。
如何做透视投影?从直观上来说就是将如图所示的台体(Frustum)挤压(squish)成长方体(Cuboid),然后再照着正交投影的步骤来即可
为规范化操作过程,在挤压的过程中,我们规定近平面(n)的4个点不变,而远平面(f)的 z 坐标和中心不会变化。
对于某一点 (x,y,z),我们假设挤压之后的点位置为 (x′,y′,z′),应当有
y′=znyx′=znx
而 z′ 还暂时不知道。
而坐标映射情况为
xyz1⇒nx/zny/zunknown1=nxnystill unknownz
此时可以得到
Mpersp→ortho=n0?00n?000?100?0
为了解出矩阵中的 ?,考虑规定的两个性质:
由第一个性质
xyn1⇒xyn1=nxnyn2n
则 Mpersp→ortho 的第三行必为 (00AB) 的形式
(00AB)xyn1=n2
⇒An+B=n2
再由第二个性质
00f1⇒00f1=00f2f
同理得到
⇒Af+B=f2
从而解得 A=n+f,B=−nf
Mpersp→ortho=n0000n0000n+f100−nf0
Mpersp=MorthoMpersp→ortho
如何定义透视投影所需的的视锥?
对于图中所示视锥。宽高比(Aspectratio=width/height),而垂直可视角度(Vertical Field of View)如图所示。有了宽高比和视锥,就能得到宽和高。