
[
x
′
y
′
]
=
[
s
0
0
s
]
[
x
y
]
(等比例缩放)
\left[

[
x
′
y
′
]
=
[
s
x
0
0
s
y
]
[
x
y
]
(x,y不同比例缩放)
\left[

[
x
′
y
′
]
=
[
−
1
0
0
1
]
[
x
y
]
(沿y轴对称反转)
\left[
沿x轴或原点对称同理
如下图,切变的跨度(
a)和y是成正比例的。坐标归一化后,也就是x每次加一个y倍的a

[
x
′
y
′
]
=
[
1
a
0
1
]
[
x
y
]
(坐标归一化后的操作)
\left[

R
θ
=
[
c
o
s
θ
−
s
i
n
θ
s
i
n
θ
c
o
s
θ
]
R_\theta =\left[
为什么引入齐次坐标?
区分向量和点,更易于表示仿射变换仿射变换就是线性的几何变换加上一个平移,包括旋转、缩放、平移、切变。
齐次坐标的意义就是让平移变换和其它线性变换一样,都能表述成一个矩阵相乘的形式!
具体做法:
Add a third coordinate (w-coordinate)
向量具有平移不变性,只表示方向和大小!
运算过程中 w 分量的值:
w
!
=
0
,
[
x
y
w
]
=
[
x
/
w
y
/
w
w
/
w
]
=
[
x
/
w
y
/
w
1
]
w != 0, \left[
translation is NOT linear transform!
平移不是线性变换,线性变换的对象是向量,向量是不存在空间位置的!平移是对点进行操作。

[
x
′
y
′
w
′
]
=
[
1
0
t
x
0
1
t
y
0
0
1
]
[
x
y
w
]
=
[
x
+
t
x
y
+
t
y
w
]
(向量的w为0,点的w为1)
\left[
Scale
S
(
s
x
,
s
y
)
=
[
s
x
0
0
0
s
y
0
0
0
1
]
S(s_x, s_y) =\left[
Rotation
R
θ
=
[
c
o
s
θ
−
s
i
n
θ
0
s
i
n
θ
c
o
s
θ
0
0
0
1
]
R_\theta =\left[
Translation
T
(
t
x
,
t
y
)
=
[
1
0
t
x
0
1
t
y
0
0
1
]
T(t_x, t_y)= \left[
执行一个操作,再执行这个操作的逆操作,相当于不变。

根据矩阵的分配率性质,多个操作可以合并成一个矩阵。

变换组合到一个矩阵时,先进行线性变换,再进行平移。
[
x
′
y
′
1
]
=
[
a
b
t
x
c
d
t
y
0
0
1
]
[
x
y
1
]
\left[
Q:如何围绕给定点进行旋转(非原点)?
A:1.平移到原点 2.旋转 3.反向平移复位

Use homogeneous coordinates again:
w 分量不为0时的扩充意义:
w ! = 0 , [ x y z w ] = [ x / w y / w z / w w / w ] = [ x / w y / w z / w 1 ] w != 0, \left[\right]=\left[" role="presentation" style="position: relative;"> x y z w \right] =\left[" role="presentation" style="position: relative;"> x / w y / w z / w w / w \right] w!=0, xyzw = x/wy/wz/ww/w = x/wy/wz/w1 " role="presentation" style="position: relative;"> x / w y / w z / w 1
Use 4x4 matrices for affine(仿射) transformations
[
x
′
y
′
z
′
1
]
=
[
a
b
c
t
x
d
e
f
t
y
g
h
i
t
z
0
0
0
1
]
[
x
y
z
1
]
\left[
先进行线性变换,再进行平移。
Rotation around x,y or z-axis沿着标准轴旋转

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) =\left[
Compose any 3D rotation from Rx,Ry, Rz沿着任意轴旋转

如图,α β γ分别对应roll pitch yaw(欧拉角)。
图形学中有一个办法,可以把任意的一个旋转分解再X,Y,Z三轴上,分别做旋转从而得到了一个公式,也就是罗德里德斯旋转公式:

罗德里德斯旋转公式给了我们一个旋转矩阵,它定义了一个旋转轴 n 和一个旋转角度 α。
我们默认旋转轴 n 是过原点的,也就是起点在原点上,方向是n这个方向,旋转角度为α。
如果想要沿着任意轴旋转,但该轴起点不是原点,则需要先将所有的物体都进行平移是的旋转轴的起点为原点,然后进行旋转,最后再平移回去。
矩阵N是两个向量叉乘写成矩阵形式。
前置概念Ⅰ:旋转矩阵的逆矩阵等于它的转置矩阵
R θ = [ c o s θ − s i n θ s i n θ c o s θ ] − − − − − − − − − − − − − R − θ = [ c o s θ s i n θ − s i n θ c o s θ ] ★ R − θ = R θ − 1 = R θ T R_\theta = \left[\right] \\ \\ ------------- \\ R_{-\theta} = \left[" role="presentation"> c o s θ − s i n θ s i n θ c o s θ \right] \\ \\ ★ R_{-\theta}=R_{\theta}^{-1}=R_{\theta}^T Rθ=[cosθsinθ−sinθcosθ]−−−−−−−−−−−−−R−θ=[cosθ−sinθsinθcosθ]★R−θ=Rθ−1=RθT" role="presentation"> c o s θ s i n θ − s i n θ c o s θ
如上公式,从矩阵中我们可以发现 R − θ = R θ T R_{-\theta}=R_{\theta}^T R−θ=RθT而在图形学中我们知道 R θ R_{\theta} Rθ 和 R − θ R_{-\theta} R−θ 是一个互逆的操作
因此 R − θ = R θ − 1 = R θ T R_{-\theta}=R_{\theta}^{-1}=R_{\theta}^T R−θ=Rθ−1=RθT
因此我们可以得出 旋转矩阵的逆等于它的转置矩阵 这一定义,之后的内容我们会用到这个性质。
在数学上,一个矩阵的逆等于它的转置矩阵我们称其为正交矩阵。
前置概念Ⅱ:变换过程
我们知道我们需要将三维空间中摄像机看到的场景最终变为一张2D的图片给显示在screen上,我们来了解具体发生了什么变换。具体是去了解如何从3D 变为 2D。
其中的过程类似于拍照片:
- Model Transformation: 让人们集合在一起并摆好姿势(设置好场景)
- View Transformation : 找到一个拍摄的角度(设置好camera位置和看的方向)
- Projection Transformation: 拍照(将camera看向的3D内容变为2D照片)
我们主要对第二步进行讲解。
首先需要定义好Camera:

至此我们通过一个点(向量),两个(单位)向量将相机给固定下来了
我们知道,当相机和物体进行相对运动时,不论怎么移动二者,我们看到的结果是一样的。

因此我们将相机从原本位置移动到原点位置,使得其Look-at direction看向 -z 方向,up-direction 是 y 正半轴。相机移动后,物体/场景跟着相机进行相同的移动,这样虽然进行了移动,但最终看到的结果是相同的。
这样做是因为可以简化很多操作,相机在(0,0,0)位置有很多的好处。

假设我们现在有一个相机,在 e 点上,gaze direction 是向量 g,up direction 是 t,我们要把点 e 给变成原点,向量 g 在 -z 轴上,t 在 y 正半轴上。
其基本思想是:
进行平移,将e点移到原点。
旋转g到-z方向上。
旋转t到+y方向上。
旋转 g 叉乘 t 得到的向量 到+x方向上。

由于我们说过一般是先进行线性变换再进行平移的,但在这里是先平移再线性变换,所以我们将T写在最右边。
平移矩阵很好写,难的是如何将g,t,g×t旋转到x,y,-z上。这时可以反过来想,我们知道g,t,g×t是如何用(x,y,z)表示的,我们只需要求出x,y,-z旋转到g,t,g×t的旋转矩阵,再加上旋转矩阵的逆矩阵 是这个旋转矩阵的转置矩阵这条性质,就可以巧妙的求出g,t,g×t给旋转到x,y,-z上的旋转矩阵。
View Transform主要做两步:
Orthographic projection (正交投影) :多用于工程制图
Perspective projection(透视投影):符合人眼的成像,会产生近大远小的效果,看起来平行线不会平行,延长的话会相交。

正交投影和透视投影本质的区别就是:是否有近大远小的效果


正交投影的思想:
Ⅰ. 我们设置camera于原点,看向-Z方向,向上是Y轴
Ⅱ. 然后我们舍弃Z轴也就是让所有物体都Z都等于0,从而我们实现了所有物体只在X轴和Y轴上
Ⅲ. 将其挤压到 [ − 1 , 1 ] ∗ [ − 1 , 1 ] [-1, 1] * [-1, 1] [−1,1]∗[−1,1]这么一个正方形内.

图形学中的实际操作:
我们定义一个立方体,left,right bottom,top far,near(但是注意我们是看向-Z方向的,far的Z轴值小,near的值大)
然后将其的中心平移到原点出,最后将其给拉成一个 [ − 1 , 1 ] 3 [-1, 1]^3 [−1,1]3的正则立方体。
具体的操作矩阵:
M
o
r
t
h
o
=
[
2
r
−
l
0
0
0
0
2
t
−
b
0
0
0
0
2
n
−
f
0
0
0
0
1
]
[
1
0
0
−
r
+
l
2
0
1
0
−
t
+
b
2
0
0
1
−
n
+
f
2
0
0
0
1
]
M_{ortho} =\left[
具体来说第一个右侧矩阵是反向平移操作,将立方体的中心点平移到原点,类似二分找中点。第二个左侧矩阵是缩放到 [ − 1 , 1 ] 3 [-1, 1]^3 [−1,1]3内,因为边长是2,所以分子设置为2,相当于等比例交叉相乘。

透视投影的思想:
Ⅰ. 将frustum给挤压成一个长方体,也就是将远平面压的和近平面一个大小。
Ⅱ. 做一次正交投影,将长方体的中心移到原点并将其压缩成 [ − 1 , 1 ] 3 [-1, 1]^3 [−1,1]3的正方体。
注意:
Ⅰ. 在挤压的过程中,近平面永远不会发生变化。
Ⅱ. 在挤压过程中,远平面上的Z值不会发生变化。
Ⅲ. 挤压过程中,远平面的中心点也不会发生变化。
关于Z值会发生改变的情况,可以想象一个场景。在你的面前是一条笔直的上山铁轨,随着距离越远,枕木之间的压缩距离应该越近。
我们知道如何做正交投影,那么接下来来讨论挤压这个frustum的矩阵如何求?


首先上图鼠标所在的右侧虚线并不是特指远平面,而是近平面到远平面之间的任意面(包含远平面)。
那么此时图中出现一组相似三角形,根据边的比例关系和已知的近平面Z值以及待挤压点的信息,可以得到挤压后点的 x ′ , y ′ x',y' x′,y′
在齐次坐标中的表示形式:
[
x
y
z
1
]
→
[
n
x
/
z
n
y
/
z
u
n
k
n
o
w
n
1
]
=
=
[
n
x
n
y
s
t
i
l
l
u
n
k
n
o
w
n
z
]
\left[
挤压矩阵:
M
p
e
r
s
p
→
o
r
t
h
o
[
x
y
z
1
]
=
[
n
x
n
y
u
n
k
n
o
w
n
z
]
M_{persp→ortho} \left[
M
p
e
r
s
p
→
o
r
t
h
o
=
[
n
0
0
0
0
n
0
0
?
?
?
?
0
0
1
0
]
M_{persp→ortho}= \left[
从而我们求出了除第三行以外的内容,接下来我们求第三行,但我们需要记住两点:


x、y依旧是变量,而替换之后的n为常量代表的是近平面的距离。总的来说就是用上述性质得到了一组
unknown为 n 2 n^2 n2的特例。

同样的,由于远平面任意一点的Z值不发生改变,取远平面的中心点(其被挤压后X和Y仍为0,且Z值不变),其坐标为(0,0,f,1)
最终推导出A,B的值,从而得到挤压矩阵 M p e r s p → o r t h o M_{persp→ortho} Mpersp→ortho。

M
p
e
r
s
p
→
o
r
t
h
o
=
[
n
0
0
0
0
n
0
0
0
0
n
+
f
−
n
f
0
0
1
0
]
M_{persp→ortho}= \left[
投影透视结论:
M
p
e
r
s
p
=
M
o
r
t
h
o
M
p
e
r
s
p
→
o
r
t
h
o
M_{persp}=M_{ortho}M_{persp→ortho}
Mpersp=MorthoMpersp→ortho