以下为个人学习笔记整理,涉及坐标内容统一用右手坐标系,课程官网

# Transformation Cont

# 三维空间下的变换(3D Transformations)

# 三维空间下的向量和点

  • 3D vector = (x,y,z,0)T(x,y,z,0)^T

  • 3D point = (x,y,z,1)T(x,y,z,1)^T

向量和点的定义和二维空间类似。

# 三维空间下的齐次坐标矩阵

(xyz1)=(abctxdeftyghitz0001)(xyz1)\begin{pmatrix} x^{\prime} \\ y^{\prime} \\ z^{\prime} \\ 1 \end{pmatrix} = \begin{pmatrix} a & b & c & t_x \\ d & e & f & t_y \\ g & h & i & t_z \\ 0 & 0 & 0 & 1 \end{pmatrix} \cdot \begin{pmatrix} x \\ y \\ z \\ 1 \end{pmatrix}

# Scale

S(sx,sy,sz)=(sx0000sy0000sz00001)S(s_x, s_y, s_z) = \begin{pmatrix} s_x & 0 & 0 & 0 \\ 0 & s_y & 0 & 0 \\ 0 & 0 & s_z & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix}

# Translation

T(tx,ty,tz)=(100tx010ty001tz0001)T(t_x, t_y, t_z) = \begin{pmatrix} 1 & 0 & 0 & t_x \\ 0 & 1 & 0 & t_y \\ 0 & 0 & 1 & t_z \\ 0 & 0 & 0 & 1 \end{pmatrix}

# 绕轴旋转

默认情况下都是绕着某个轴,逆时针旋转。

image-20201228171756050

绕 X 轴旋转的情况下,x 坐标是不变的,所以,第一行和第一列不受影响

绕 x 轴 旋转:Rx(α)=(10000cosαsinα00sinαcosα00001)\text{绕 x 轴 旋转:} \quad R_x(\alpha) = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & \cos \alpha & - \sin \alpha & 0 \\ 0 & \sin \alpha & \cos \alpha & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix}

绕 Y 轴旋转的情况下,y 坐标是不变的,所以,第二行和第二列不受影响

绕 y 轴 旋转:Ry(α)=(cosα0sinα00100sinα0cosα00001)\text{绕 y 轴 旋转:} \quad R_y(\alpha) = \begin{pmatrix} \cos \alpha & 0 & \sin \alpha & 0 \\ 0 & 1 & 0 & 0 \\ - \sin \alpha & 0 & \cos \alpha & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix}

绕 Z 轴旋转的情况下,z 坐标是不变的,所以,第三行和第三列不受影响

绕 z 轴 旋转:Rz(α)=(cosαsinα00sinαcosα0000100001)\text{绕 z 轴 旋转:} \quad R_z(\alpha) = \begin{pmatrix} \cos \alpha & - \sin \alpha & 0 & 0 \\ \sin \alpha & \cos \alpha & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix}

# 为什么 RyR_y 看起来是反的?

因为 x,y,z 之前的循环对称关系,导致,其中总会有一组坐标的相乘是反向的。

x^×y^=z^\hat x \times \hat y = \hat z

y^×z^=x^\hat y \times \hat z = \hat x

z^×x^=y^\hat z \times \hat x = - \hat y

x^×z^=y^\hat x \times \hat z = \hat y

# 3D 旋转

欧拉角(Euler angles):Rxyz(α,β,γ)=Rx(α)Ry(β)Rz(γ)\text{欧拉角(Euler angles):} \quad R_{xyz}(\alpha,\beta,\gamma) = R_x(\alpha)R_y(\beta)R_z(\gamma)

# 观测变换(Viewing transformation)

  • Model(模型)transformation:把场景的物体摆放好
  • View(视图)/ Camera transformation:把摄像机放在一个合适的位置
  • Projection(投影)
    • Orthographic(正交)
    • Perspective(透视)

# 视图📷

  • Position: e\vec e
  • Look-at / gaze direction:g\vec g
  • Up direction:t\vec t

# 观察的关键

image-20201228174243349

  • 相机和物体的距离
  • 相机的角度

只要保证上述两点,不论何地,最终的画面就不会改变。所以通常情况下,会把相机放在「原点坐标」。

# 如何把相机移动到原点,且 g=z\vec g = -\vec z

Mview=RviewTviewM_{view} = R_{view} \cdot T_{view}

  • 把相机移动到原点

Tview=[100xe010ye001ze0001]T_{view} = \begin{bmatrix} 1 & 0 & 0 & -x_e \\ 0 & 1 & 0 & -y_e \\ 0 & 0 & 1 & -z_e \\ 0 & 0 & 0 & 1 \end{bmatrix}

  • g\vec g 旋转到 z-\vec z,把 t\vec t旋转到 y\vec y, 然后通过 g×t\vec g \times \vec t得到 x\vec x

    • 可以简化成从正常的坐标系,旋转得到相机的坐标系,然后把旋转角度取反。

假设:Mview=[xg×txtxgyg×tytygzg×tztzg]\text{假设:} \quad M_{view} = \begin{bmatrix} x_{\vec g \times \vec t} & x_t & x_{-g}\\ y_{\vec g \times \vec t} & y_t & y_{-g}\\ z_{\vec g \times \vec t} & z_t & z_{-g} \end{bmatrix}

x^view=[xg×tyg×tzg×t0],y^view=[xtytzt0],z^view=[xgygzg0]\hat x_{view} = \begin{bmatrix} x_{\vec g \times \vec t}\\ y_{\vec g \times \vec t}\\ z_{\vec g \times \vec t}\\ 0 \end{bmatrix} ,\quad \hat y_{view} = \begin{bmatrix} x_t\\ y_t\\ z_t\\ 0 \end{bmatrix} ,\quad \hat z_{view} = \begin{bmatrix} x_{-g}\\ y_{-g}\\ z_{-g}\\ 0 \end{bmatrix}

  • 如何把正常的坐标向量转化为 MviewM_{view} 的坐标向量呢?

正常的坐标矩阵:Mnormal=[100010001]\text{正常的坐标矩阵:} \quad M_{normal} = \begin{bmatrix} 1 & 0 & 0\\ 0 & 1 & 0\\ 0 & 0 & 1 \end{bmatrix}

x^normal=[1000],y^normal=[0100],z^normal=[0010]\hat x_{normal} = \begin{bmatrix} 1\\ 0\\ 0\\ 0 \end{bmatrix} ,\quad \hat y_{normal} = \begin{bmatrix} 0\\ 1\\ 0\\ 0 \end{bmatrix} ,\quad \hat z_{normal} = \begin{bmatrix} 0\\ 0\\ 1\\ 0 \end{bmatrix}

Rx^normal=x^view,Ry^normal=y^view,Rz^normal=z^viewR \cdot \hat x_{normal} = \hat x_{view} ,\quad R \cdot \hat y_{normal} = \hat y_{view} ,\quad R \cdot \hat z_{normal} = \hat z_{view}

  • 通过上述公式,可以把 R 的矩阵求出来。那么从正常坐标向量变换到摄像机的坐标向量的矩阵就可以求得(Rview1{R_{view}}^{-1}

Rview1=[xg×txtxg0yg×tytyg0zg×tztzg00001]{R_{view}}^{-1} = \begin{bmatrix} x_{\vec g \times \vec t} & x_t & x_{-g} & 0\\ y_{\vec g \times \vec t} & y_t & y_{-g} & 0 \\ z_{\vec g \times \vec t} & z_t & z_{-g} & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}

  • 然后再对 Rview1{R_{view}}^{-1} 取逆矩阵,就可以得到,从摄像机坐标变换到正常世界坐标的矩阵(RviewR_{view}

Rview=[xg×tyg×tzg×t0xtytzt0xgygzg00001]R_{view} = \begin{bmatrix} x_{\vec g \times \vec t} & y_{\vec g \times \vec t} & z_{\vec g \times \vec t} & 0\\ x_t & y_t & z_t & 0 \\ x_{-g} & y_{-g} & z_{-g} & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}

# Projection📽

# 正交(Orthographic)投影

image-20201228212823621

  • 相机 lookat: z-\vec z,up:y\vec y

image-20201231112436972

  • Z 坐标就可以丢弃了~🙌

    • 如何区分前后呢❓
  • 不论 x,y 有多大,全部变换到 [1,1]2{[-1, 1]}^{2} 的平面上

    • 方便后续对不同分辨率大小进行适配。
# 正交投影也可以被看作是一个立方体:

image-20201231155824631

# 一般情况下正则化(canonical)立方体的做法

将一个任意的长方体,转换为一个标准的正方体。

  • 把长方体定义成一个 x,y,z 坐标上的范围 x:[l,r],y:[b,t],z:[f,n]x:[l,r],\quad y:[b, t],\quad z:[f, n]

Cube=[lr]×[bt]×[fn]Cube = \begin{bmatrix} l & r \end{bmatrix} \times \begin{bmatrix} b & t \end{bmatrix} \times \begin{bmatrix} f & n \end{bmatrix}

image-20201231113534193

  • Translate:

Mortho=[100r+l2010t+b2001n+f20001]Mortho{M_{ortho}}^{\prime} = \begin{bmatrix} 1 & 0 & 0 & -\frac{r+l}{2} \\ 0 & 1 & 0 & -\frac{t+b}{2} \\ 0 & 0 & 1 & -\frac{n+f}{2} \\ 0 & 0 & 0 & 1 \end{bmatrix} \cdot M_{ortho}

  • Scale:

Mortho=[2rl00002tb00002nf00001]Mortho{M_{ortho}}^{\prime\prime} = \begin{bmatrix} \frac{2}{r-l} & 0 & 0 & 0 \\ 0 & \frac{2}{t-b} & 0 & 0 \\ 0 & 0 & \frac{2}{n-f} & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} \cdot {M_{ortho}}^{\prime}

# 透视(Perspective)投影

image-20201228212755325

  • 如何表示透视投影下的坐标点:任意三维坐标都可以转为(xz,yz,z2,z!=0)(xz , yz , z^2 , z!=0)
    • 远处的物体,投影到近处以后,大小会随着 Z 的变化而变化 (1,0,0,1)=(2,0,0,2)(1,0,0,1) = (2,0,0,2)

(x,y,z,1)(kx,ky,kz,k!=0)(xz,yz,z2,z!=0)(x , y , z , 1) \quad \to \quad (kx , ky , kz , k!=0) \quad \to \quad (xz , yz , z^2 , z!=0)

# 透视投影则更像是一个四棱台:

对透视投影通常可以看作是把远平面变换成近屏幕的大小,在对其做正交投影

  • 挤压的两个特性:
    • 远平面的挤压,不会修改 z 的值。
    • 远平面的中心点在挤压和不挤压,都位于远平面的中心。

image-20201231160609949

  • 变换远平面大小:

image-20201231161327352

y=nzy,x=nzxy^{\prime} = \frac{n}{z}y ,\quad x^{\prime} = \frac{n}{z}x

(xyz1)(nxznyzunknow1)==(nxnyunknowz)\begin{pmatrix} x \\ y \\ z \\ 1 \end{pmatrix} \quad \implies \quad \begin{pmatrix} \frac{nx}{z} \\ \frac{ny}{z} \\ unknow \\ 1 \end{pmatrix} == \begin{pmatrix} nx \\ ny \\ unknow \\ z \end{pmatrix}

  • 通过变换前后的坐标点,可以算出变换矩阵:

Mpersp>ortho(xyz1)=(nxnyunknowz)Mpersp>ortho=(n0000n00????0010)M_{persp->ortho} \cdot \begin{pmatrix} x \\ y \\ z \\ 1 \end{pmatrix} = \begin{pmatrix} nx \\ ny \\ unknow \\ z \end{pmatrix} \quad \to \quad M_{persp->ortho} = \begin{pmatrix} n & 0 & 0 & 0 \\ 0 & n & 0 & 0 \\ ? & ? & ? & ? \\ 0 & 0 & 1 & 0 \end{pmatrix}

  • 推断第三行的值:

设 z = n,(xyz1)=(nxnynzn)=(nxnyunknowz)unknow=n2,(nxnyn2n)\text{设 z = n,} \quad \begin{pmatrix} x \\ y \\ z \\ 1 \end{pmatrix} = \begin{pmatrix} nx \\ ny \\ nz \\ n \end{pmatrix} = \begin{pmatrix} nx \\ ny \\ unknow \\ z \end{pmatrix} \quad \implies \quad unknow=n^2 ,\quad \begin{pmatrix} nx \\ ny \\ n^2 \\ n \end{pmatrix}

n2=(?,?,?,?)(xyn1),与x,y无关(?,?,?,?)=(0,0,?1,?2)?1n+?2=n2n^2= (?,?,?,?) \cdot \begin{pmatrix} x \\ y \\ n \\ 1 \end{pmatrix} \text{,与x,y无关} \quad \to \quad (?,?,?,?) = (0,0,?_1,?_2) \quad \to \quad ?_1n + ?_2 = n^2

  • 平面的中心点在挤压和不挤压,都位于平面的中心
    • 所以 (0,0,n,1)=(0,0,n2,n)(0,0,n,1)=(0,0,n^2,n),近点挤压后依旧是近点
    • 所以 (0,0,f,1)=(0,0,f2,f)(0,0,f,1)=(0,0,f^2,f),远点挤压后依旧是远点(这里假设远平面距离f=zf = z
    • 最终的结果就是:先挤压 Mpersp>orthoM_{persp->ortho} 再平移,再缩放 MorthoM_{ortho},最终得到透视投影

?1n+?2=n2,?1f+?2=f2?1=n+f,?2=nf?_1n + ?_2 = n^2 ,\quad ?_1f + ?_2 = f^2 \quad \implies \quad ?_1 = n + f ,\quad ?_2 = -nf

最终矩阵结果:Mpresp=MorthoMpersp>ortho=(2rl00002tb00002nf00001)(100r+l2010t+b2001n+f20001)(n0000n0000n+fnf0010)\text{最终矩阵结果:}\quad M_{presp} = M_{ortho}M_{persp->ortho} = \begin{pmatrix} \frac{2}{r-l} & 0 & 0 & 0 \\ 0 & \frac{2}{t-b} & 0 & 0 \\ 0 & 0 & \frac{2}{n-f} & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} \begin{pmatrix} 1 & 0 & 0 & -\frac{r+l}{2} \\ 0 & 1 & 0 & -\frac{t+b}{2} \\ 0 & 0 & 1 & -\frac{n+f}{2} \\ 0 & 0 & 0 & 1 \end{pmatrix} \begin{pmatrix} n & 0 & 0 & 0 \\ 0 & n & 0 & 0 \\ 0 & 0 & n+f & -nf \\ 0 & 0 & 1 & 0 \end{pmatrix}