transformation
什么是变换
由上图可知,以人眼位置为一摄像机,将三维世界转换为二维平面就叫投影变换
2D·transform
缩放变换
均匀
[ x ′ y ′ ] = [ s 0 0 s ] [ x y ] \begin{bmatrix} x'\\ y' \end{bmatrix} = \begin{bmatrix} s & 0\\ 0 & s \end{bmatrix} \begin{bmatrix} x\\ y \end{bmatrix} [x′y′]=[s00s][xy]
不均匀
对称变换
切变
由上图可知,竖直方向(y)未发生改变,水平方向最底层无变化,y=1时变化为a,则可以写成
x
′
=
x
+
a
y
x'=x+ay
x′=x+ay
旋转(默认旋转中心为(0,0),方向为逆时针)
推导
- 对任意一点满足旋转公式(特殊点也满足)
旋转 θ 角 和 -θ 角
R θ = ( cos θ − sin θ sin θ cos θ ) R_\theta = \begin{pmatrix} \cos\theta & -\sin\theta \\ \sin\theta & \cos\theta \end{pmatrix} Rθ=(cosθsinθ−sinθcosθ)
R
−
θ
=
(
cos
θ
sin
θ
−
sin
θ
cos
θ
)
=
R
θ
T
R_{-\theta} = \begin{pmatrix} \cos\theta & \sin\theta \\ -\sin\theta & \cos\theta \end{pmatrix} =R^T_\theta
R−θ=(cosθ−sinθsinθcosθ)=RθT
R
−
θ
=
R
θ
−
1
R_{-\theta}=R^{-1}_\theta
R−θ=Rθ−1
旋转中,旋转的逆等于其转置(正交矩阵)
线性变换(x’=Mx)
上述变换都可以携程
x'=Mx
形式
平移变换(线性变换不适用,引入齐次坐标统一x'=Mx
)
对于平移变换,在x方向向右平移tx,y方向向上平移ty。发现并没有一个线性变换矩阵x'=Mx
满足这种简单的变换。
则上述平移变换只能写成以下形式 [ x ′ y ′ ] = [ a b c d ] [ x y ] + [ t x 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} [x′y′]=[acbd][xy]+[txty]
这种形式并非线性变换
,而是仿射变换
什么是齐次坐标
齐次坐标是一个用于投影几何里的坐标系统,它将一个原本是n维的向量用一个n+1维向量来表示。具体来说,给定欧氏平面上的一点(x,y),对任意非零实数Z,三元组(xZ,yZ,Z)即称之为该点的齐次坐标。在计算机图形学中,齐次坐标是一个重要的工具,它既能够用来明确区分向量和点,同时也更易用于进行仿射(线性)几何变换。
齐次坐标的主要作用在于合并矩阵运算中的乘法和加法,为将二维、三维甚至高维空间中的一个点集从一个坐标系变换到另一个坐标系提供了有效的方法。许多图形应用涉及到几何变换,主要包括平移、旋转、缩放。以矩阵表达式来计算这些变换时,平移是矩阵相加,旋转和缩放则是矩阵相乘。引入齐次坐标后,这些变换可以统一为矩阵乘法运算,从而简化了计算过程。
此外,齐次坐标在处理透视投影等问题时具有独特的优势。在欧氏几何空间,两条平行线不能相交;然而,在透视几何空间里面,两条平行线可以相交。齐次坐标能够处理这种在透视投影中出现的平行线相交的情况,因此在计算机图形学、计算机视觉等领域有着广泛的应用。
简而言之,齐次坐标是一个强大的数学工具,它能够简化几何变换的计算,处理透视投影等问题。
引入齐次坐标
通过齐次坐标,以增加一个数的方式,可以将上述平移变换也写成x'=Mx
这种形式。所得的x+tx
和y+ty
正是我们所需要的。
为什么齐次坐标后加上 1 表示点,而加上 0 表示向量
-
这个1表示这是一个具有确定位置的点。无论我们如何缩放这个点(例如,通过乘以一个非零实数),只要最后一项保持为1,我们就可以通过简单的除法操作恢复原始的点位置。
-
相反,当我们用齐次坐标来表示一个向量时,通常会在坐标的最后加上一个0。这里的0表示这是一个有方向但没有固定起点或终点的线段。向量只关心方向,不关心具体位置或长度。因此,无论我们如何缩放这个向量,只要它的方向保持不变,它就仍然表示同一个向量。
向量具有平移不变性:
如上述平移可知,若向量经过上述平移变换,我们希望得到的是 [ x y ] \begin{bmatrix} x\\y\end{bmatrix} [xy]
而不是
[ x + t x y + t y ] \begin{bmatrix} x+t_{x} \\ y+t_{y} \end{bmatrix} [x+txy+ty]2.
由上述可知,在齐次坐标中,点+点为这两个点的中点,因为w=2
,所以得出点为两点中点
仿射变换+齐次坐标=x'=Mx
2D变换所有形式
则对于所有2D的变换可以写为
注意:并非所有情况最后一条都为(0,0,1),在投影变换等其他情况并非这样。
逆变换
组合变换
很显然,第一幅图并不能直接一步得到第二幅图。
可以通过两步得到:平移+旋转
- 先平移再旋转
- 先旋转再平移
很显然第二种方式才是正确的
上述由一种状态到另一种状态可以通过变换的组合形成,且组合的顺序不可发生改变,由此想到矩阵乘法(不满足交换律)
组合变换原则—先变换的总是先乘在矩阵左边(从右向左)
根据矩阵结合率可知,再复杂的变化仍然可以通过(3*3)的矩阵表示。
变换分解
要对上述图形做旋转,那么可以先平移至原点,旋转后放回原位。
3D·transform
同二维一样,我们也可以引入齐次坐标对其进行旋转,平移,缩放。
x'=Mx
那么这个(4*4)的矩阵先表示平移还是线性变换呢?
同二维组合变化可知 是
先线性变换再平移
缩放,平移
旋转
这里可以看出绕y轴旋转的矩阵由点不同,根据右手螺旋定则可知
绕轴旋转所得矩阵的推导主要基于线性代数和三角学的知识。以下以绕
z
z
z轴旋转为例,简要说明其推导过程:
首先,设三维空间中一点 P P P的坐标为 ( x , y , z ) (x, y, z) (x,y,z),当该点绕 z z z轴逆时针旋转 θ \theta θ角后到达点 P ′ P' P′,其坐标为 ( x ′ , y ′ , z ′ ) (x', y', z') (x′,y′,z′)。由于点 P P P绕 z z z轴旋转,因此其 z z z坐标保持不变,即 z ′ = z z' = z z′=z。
接下来,考虑 x x x和 y y y坐标的变化。由于旋转是在二维平面上进行的(垂直于 z z z轴的平面),我们可以利用二维平面上的旋转公式。在二维平面上,一个点 ( x , y ) (x, y) (x,y)绕原点逆时针旋转 θ \theta θ角后,其新的坐标 ( x ′ , y ′ ) (x', y') (x′,y′)可以通过以下公式计算:
x ′ = x cos θ − y sin θ y ′ = x sin θ + y cos θ \begin{aligned} x' &= x\cos\theta - y\sin\theta \\ y' &= x\sin\theta + y\cos\theta \end{aligned} x′y′=xcosθ−ysinθ=xsinθ+ycosθ
这个公式可以通过三角函数的性质推导出来,它描述了二维平面上点的旋转。
现在,我们将这个二维旋转公式扩展到三维空间中绕 z z z轴旋转的情况。由于 z z z坐标不变,我们只需要关注 x x x和 y y y坐标的变化。因此,三维空间中点 P P P绕 z z z轴旋转后的坐标 P ′ P' P′可以表示为:
x ′ = x cos θ − y sin θ y ′ = x sin θ + y cos θ z ′ = z \begin{aligned} x' &= x\cos\theta - y\sin\theta \\ y' &= x\sin\theta + y\cos\theta \\ z' &= z \end{aligned} x′y′z′=xcosθ−ysinθ=xsinθ+ycosθ=z
这个旋转过程可以用一个 3 × 3 3 \times 3 3×3的矩阵来表示,即绕 z z z轴旋转的旋转矩阵 R z ( θ ) R_z(\theta) Rz(θ):
R z ( θ ) = [ cos θ − sin θ 0 sin θ cos θ 0 0 0 1 ] R_z(\theta) = \begin{bmatrix} \cos\theta & -\sin\theta & 0 \\ \sin\theta & \cos\theta & 0 \\ 0 & 0 & 1 \end{bmatrix} Rz(θ)= cosθsinθ0−sinθcosθ0001
通过将原始坐标向量 [ x , y , z ] [x, y, z] [x,y,z]与这个旋转矩阵相乘,就可以得到旋转后的坐标向量 [ x ′ , y ′ , z ′ ] [x', y', z'] [x′,y′,z′]:
类似地,绕
x
x
x轴和绕
y
y
y轴的旋转矩阵也可以通过类似的方法推导出来。这些基本旋转矩阵可以组合起来,通过矩阵乘法,实现更复杂的旋转操作。
旋转组合
以飞机为例,任何方向的旋转可以分解为
x
y
z
x y z
xyz三个方向
这里我们引入罗德里格斯旋转公式
将旋转角定义为 α \alpha α 旋转轴定义为 n n n
默认 n n n过原点,方向则与 n ⃗ \vec{n} n同向。旋转时与二维同理,现将其移至原点,旋转后再移回。
公式原理
罗德里格旋转公式可以转化为一个3x3的旋转矩阵,这个矩阵表示了绕单位向量 k = ( k x , k y , k z ) \mathbf{k} = (k_x, k_y, k_z) k=(kx,ky,kz) 旋转 θ \theta θ 角度的线性变换。这个旋转矩阵 R \mathbf{R} R 可以表示为:
R = cos θ I + ( 1 − cos θ ) k T k + sin θ [ k ] × \mathbf{R} = \cos\theta \mathbf{I} + (1 - \cos\theta)\mathbf{k}^T\mathbf{k} + \sin\theta[\mathbf{k}]_\times R=cosθI+(1−cosθ)kTk+sinθ[k]×
其中:
- I \mathbf{I} I 是3x3的单位矩阵。
- k T \mathbf{k}^T kT 是向量 k \mathbf{k} k 的转置。
- k T k \mathbf{k}^T\mathbf{k} kTk 是一个3x3的矩阵,其元素是 k \mathbf{k} k 的各分量与自身的乘积。
- [ k ] × [\mathbf{k}]_\times [k]× 是向量 k \mathbf{k} k 的叉积矩阵(也称为外积矩阵或斜对称矩阵),其形式如下:
[ k ] × = [ 0 − k z k y k z 0 − k x − k y k x 0 ] [\mathbf{k}]_\times = \begin{bmatrix} 0 & -k_z & k_y \\ k_z & 0 & -k_x \\ -k_y & k_x & 0 \end{bmatrix} [k]×= 0kz−ky−kz0kxky−kx0
因此,旋转矩阵 R \mathbf{R} R 可以具体写为:
R = [ cos θ + ( 1 − cos θ ) k x 2 ( 1 − cos θ ) k x k y − sin θ k z ( 1 − cos θ ) k x k z + sin θ k y ( 1 − cos θ ) k y k x + sin θ k z cos θ + ( 1 − cos θ ) k y 2 ( 1 − cos θ ) k y k z − sin θ k x ( 1 − cos θ ) k z k x − sin θ k y ( 1 − cos θ ) k z k y + sin θ k x cos θ + ( 1 − cos θ ) k z 2 ] \mathbf{R} = \begin{bmatrix} \cos\theta + (1 - \cos\theta)k_x^2 & (1 - \cos\theta)k_x k_y - \sin\theta k_z & (1 - \cos\theta)k_x k_z + \sin\theta k_y \\ (1 - \cos\theta)k_y k_x + \sin\theta k_z & \cos\theta + (1 - \cos\theta)k_y^2 & (1 - \cos\theta)k_y k_z - \sin\theta k_x \\ (1 - \cos\theta)k_z k_x - \sin\theta k_y & (1 - \cos\theta)k_z k_y + \sin\theta k_x & \cos\theta + (1 - \cos\theta)k_z^2 \end{bmatrix} R= cosθ+(1−cosθ)kx2(1−cosθ)kykx+sinθkz(1−cosθ)kzkx−sinθky(1−cosθ)kxky−sinθkzcosθ+(1−cosθ)ky2(1−cosθ)kzky+sinθkx(1−cosθ)kxkz+sinθky(1−cosθ)kykz−sinθkxcosθ+(1−cosθ)kz2
这个旋转矩阵 R \mathbf{R} R 可以直接应用于任何三维向量 v \mathbf{v} v,通过矩阵乘法得到旋转后的向量 v rot \mathbf{v}_{\text{rot}} vrot:
v rot = R v \mathbf{v}_{\text{rot}} = \mathbf{R} \mathbf{v} vrot=Rv
在图形学中,这种矩阵形式的旋转操作非常高效,因为现代图形硬件通常都支持向量与矩阵的并行乘法运算。通过将旋转操作编码为矩阵,我们可以利用这些硬件加速功能来快速渲染旋转后的物体。
从三维到二维
从拍照引入
从模型到投影自然就从三维转至二维。这里提到了一个重要模式(MVP模式)
MVP模式将应用程序分为三个主要的组成部分:
Model(模型)
:表示应用程序的业务逻辑和数据,负责处理数据的获取、处理和存储。它不依赖于View和Presenter,因此可以被其他部分复用。
View(视图)
:显示数据和与用户交互的部分,负责展示界面和响应用户的输入。View不包含业务逻辑,仅负责将用户的操作传递给Presenter。
Presenter(呈现者)
:充当View和Model之间的中介,负责处理View的事件和用户输入,并对Model进行操作。Presenter从Model获取数据,并将更新后的数据传递给View显示给用户。MVP模式的关键概念是View和Model之间的解耦,通过Presenter来协调它们之间的交互。这种解耦使得各个组件可以独立开发、测试和修改,从而提高了应用程序的可维护性和可测试性。
MVP模式的工作流程如下:
- 用户与View进行交互,例如点击按钮或输入文本。 View将交互事件传递给Presenter。
- Presenter接收到事件后,根据业务逻辑对Model进行操作。 Presenter从Model获取更新后的数据。
- Presenter将更新后的数据传递给View进行显示。
MVP模式的优点:
- 分离关注点:View只负责用户界面的显示,Presenter负责处理业务逻辑,Model负责数据的处理,各自职责清晰明确。
- 可测试性:由于MVP模式解耦了View和Model,因此可以更容易地对Presenter和Model进行单元测试。
- 可维护性:各个组件互不依赖,使得修改和维护代码更加容易,也降低了引入新功能或更改需求的风险。
怎么定义相机
- 相机位置
- 观测方向
- 相机向上方向
确定相机摆放位置,观测方向,向上方向
相机放在原点,观测方向为 − z -z −z,向上方向为 y y y
如何移动
先做平移,再旋转(从右向左原则)
正向旋转不好写,先做逆旋转,从
x
x
x轴旋转到
g
×
t
g×t
g×t,再做一次逆就好了
投影方式
正交投影
正交投影:
正交投影是一种平行投影方式,它将场景中的物体投影到一个平行于观察平面的平面上,投影后的图像保持物体的大小和平行关系。在正交投影中,平行线在投影平面上依然是平行的。正交投影不考虑物体与观察者之间的距离,所有的物体都以相同的比例投影到屏幕上。
正交投影的数学公式为:
x
′
=
x
/
d
x' = x / d
x′=x/d
y
′
=
y
/
d
y' = y / d
y′=y/d
z
′
=
z
/
d
z' = z / d
z′=z/d
其中,
(
x
′
,
y
′
,
z
′
)
(x', y', z')
(x′,y′,z′)是投影后的二维坐标,
(
x
,
y
,
z
)
(x, y, z)
(x,y,z)是三维场景中的物体坐标,d是一个参数,用于控制投影的大小。正交投影通常用于工程制图、CAD(计算机辅助设计)等领域。
无论远处物体还是近处物体,在投影平面看来大小是不变的,放在一张图即可,忽略深度(即忽略 z z z)
正式做法
- 无论物体在哪儿,先移至原点,再经过伸缩变换至 [ − 1 , 1 ] 3 [-1,1]^3 [−1,1]3上
- 定义远近
[
f
,
n
]
[f,n]
[f,n]是对于
z
z
z轴,因为我们是沿着
−
z
-z
−z方向看
透视投影
透视投影:
透视投影模拟了人眼观察物体时的透视效果,它根据物体与观察者之间的距离将物体投影到观察平面上。透视投影可以产生更真实、更具逼真感的图像。在透视投影中,物体的远近和大小会受到观察者的距离的影响,离观察者越近的物体会显得更大,离观察者越远的物体会显得更小。
透视投影的数学公式可以表示为:
x
′
=
x
/
(
d
−
z
)
x' = x / (d - z)
x′=x/(d−z)
y
′
=
y
/
(
d
−
z
)
y' = y / (d - z)
y′=y/(d−z)
其中,
(
x
′
,
y
′
)
(x', y')
(x′,y′)是投影后的二维坐标,
(
x
,
y
,
z
)
(x, y, z)
(x,y,z)是物体在三维空间中的坐标,d是观察者到投影平面的距离。
透视投影常用于计算机游戏、虚拟现实和电影特效等领域,因为它能够提供更加真实的场景感觉和逼真的景深效果。
- 运用最广泛的投影
- 近大远小
- 平行线不再平行
回顾齐次坐标
(
x
,
y
,
z
,
1
)
(x,y,z,1)
(x,y,z,1)和
(
k
x
,
k
y
,
k
z
,
k
!
=
0
)
(kx,ky,kz,k!=0)
(kx,ky,kz,k!=0)表示想同点,若
k
=
z
k=z
k=z那么也满足
定义近的平面小,远的平面大,从远端到近端最后会形成一个点,所以只用将远端挤压至近端想同大小再经过正交投影即可获得最后效果。
- z z z不会变
- 中心点不会变
- 任何一点,对于 ( x , y , n , 1 ) (x,y,n,1) (x,y,n,1)(近平面 z = n z=n z=n),在近平面不发生改变
-
z
z
z不发生改变,无论远近
远端映射回近端 ( x y n 1 ) = ( n x n y n 2 n ) \begin{pmatrix} x\\ y\\ n\\ 1 \end{pmatrix}=\begin{pmatrix} nx\\ ny\\ n^2\\ n \end{pmatrix} xyn1 = nxnyn2n
又 ( 0 , 0 , f , 1 ) (0,0,f,1) (0,0,f,1)远平面中心变换后还是 ( 0 , 0 , f , 1 ) (0,0,f,1) (0,0,f,1)
再次回顾上述公式,那么对于近远平面中心点p,经过变换后是更靠近远端还是更靠近近端呢?
根据相似三角形原理推导得出。假设观察者位于原点(0, 0, 0),投影平面位于z = d处(d为观察者到投影平面的距离)。对于物体的三维坐标(x, y, z),其在透视投影后的二维坐标为(x’, y’)。
通过相似三角形原理,我们可以得到以下关系:
x
′
/
x
=
(
d
−
z
)
/
d
x' / x = (d - z) / d
x′/x=(d−z)/d
y
′
/
y
=
(
d
−
z
)
/
d
y' / y = (d - z) / d
y′/y=(d−z)/d
进一步整理可得透视投影的数学公式:
x
′
=
(
x
∗
d
)
/
(
d
−
z
)
x' = (x * d) / (d - z)
x′=(x∗d)/(d−z)
y
′
=
(
y
∗
d
)
/
(
d
−
z
)
y' = (y * d) / (d - z)
y′=(y∗d)/(d−z)
这些公式描述了物体坐标到投影坐标的转换过程。
解释一下这些公式的含义:
x
、
y
、
z
x、y、z
x、y、z是三维物体坐标,表示物体在世界坐标系中的位置。
x
′
、
y
′
x'、y'
x′、y′是透视投影后的二维坐标,表示物体在投影平面上的位置。
d
d
d是观察者到投影平面的距离,它决定了透视投影的效果。
在透视投影公式中,当物体距离观察者较远时,即z较大,分母
(
d
−
z
)
(d − z)
(d−z)就会变大,导致投影后的位置较小,产生了视角收缩的效果。当物体靠近观察者时,即z较小,分母
(
d
−
z
)
(d − z)
(d−z)变小,导致投影后的位置较大,产生了物体变大的效果。
需要注意的是,透视投影的数学公式只是一种模拟透视效果的近似计算方法,并不完全准确地模拟真实的光学透视。真实的光学透视是一个更加复杂的过程,涉及到光线的传播和折射等光学现象。透视投影公式是为了在计算机图形学中模拟和渲染逼真的透视效果而推导出来的近似方法。