图形学基础-变换

本文深入探讨图形学中的基本变换原理,包括2D和3D空间中的旋转、缩放、错切和平移等操作,详细讲解了齐次坐标、仿射变换、投影变换以及相机变换的概念与应用。

图形学基础-变换

  • 2D transformations: rotation, scale, shear

  • Homogeneous coordinates(齐次坐标)

  • Composite transform(变换复合)

  • 3D transformations(3D变换)

  • Viewing (观测) transformation(视图变换相关)

    • View (视图) /Camera transformation (视图变换)
    • Projection (投影) transformation
      • Orthographic (正交) projection (正交投影)
      • Perspective (透视) projection (透视投影)

2D线性变换

缩放(Scale)
Scale(sx,sy)=[sx00sy][sx00sy]∗[xy]=[sxxsyy] Scale(s_x,s_y) =\begin{bmatrix} s_x & 0 \\ 0 & s_y \end{bmatrix}\\ \begin{bmatrix} s_x & 0 \\ 0 & s_y \end{bmatrix}* \begin{bmatrix} x\\ y \end{bmatrix}= \begin{bmatrix} s_xx\\ s_yy \end{bmatrix} Scale(sx,sy)=[sx00sy][sx00sy][xy]=[sxxsyy]
错切(Shear)
shear_x(s)=[1s01],shear_y(s)=[1001][10s1]∗[xy]=[xsx+y] shear\_x(s) =\begin{bmatrix} 1 & s \\ 0 & 1 \end{bmatrix}, shear\_y(s) =\begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix}\\ \begin{bmatrix} 1 & 0 \\ s & 1 \end{bmatrix}* \begin{bmatrix} x\\ y \end{bmatrix}= \begin{bmatrix} x\\ sx+y \end{bmatrix} shear_x(s)=[10s1],shear_y(s)=[1001][1s01][xy]=[xsx+y]
旋转(rotation)
rotation(ϕ)=[cos⁡ϕ−sin⁡ϕsin⁡ϕcos⁡ϕ][cos⁡ϕ−sin⁡ϕsin⁡ϕcos⁡ϕ]∗[xy]=[xcos⁡ϕ−ysin⁡ϕxsin⁡ϕ+ycos⁡ϕ] rotation(\phi) =\begin{bmatrix} \cos{\phi} & -\sin{\phi} \\ \sin{\phi} & \cos{\phi} \end{bmatrix}\\ \begin{bmatrix} \cos{\phi} & -\sin{\phi} \\ \sin{\phi} & \cos{\phi} \end{bmatrix}* \begin{bmatrix} x\\ y \end{bmatrix}= \begin{bmatrix} x\cos{\phi}-y\sin{\phi}\\ x\sin{\phi}+y\cos{\phi} \end{bmatrix} rotation(ϕ)=[cosϕsinϕsinϕcosϕ][cosϕsinϕsinϕcosϕ][xy]=[xcosϕysinϕxsinϕ+ycosϕ]
这旋转矩阵表示将向量(或点)绕原点逆时针旋转ϕ\phiϕ

翻转(reflection)

reflect_x=[−1001],reflect_y=[100−1][−1001]∗[xy]= reflect\_x =\begin{bmatrix} -1 & 0 \\ 0 & 1 \end{bmatrix}, reflect\_y =\begin{bmatrix} 1 & 0 \\ 0 & -1 \end{bmatrix}\\ \begin{bmatrix} -1 & 0 \\ 0 & 1 \end{bmatrix}* \begin{bmatrix} x\\ y \end{bmatrix}= reflect_x=[1001],reflect_y=[1001][1001][xy]=

平移(Translation)

平移能否使用2维矩阵表示吗?

**对于任意一个点的平移(向量具有平移不变性)**它有如下形式
xt=x+tx;yt=y+ty x_t = x+t_x;y_t=y+t_y xt=x+tx;yt=y+ty
平移无法使用一个2x2的矩阵来表示!因此引入齐次坐标

齐次坐标(Homogeneous coordinates)

给二维点或向量增加一个维度:

2D向量:(x,y)T=>(x,y,0)T(x,y)^T=>(x,y,0)^T(x,y)T=>(x,y,0)T

2D点 :(x,y)T=>(x,y,1)T(x,y)^T=>(x,y,1)^T(x,y)T=>(x,y,1)T

对于2D点(x,y,w)T=>(x/w,y/w)Tw!=0(x,y,w)^T=>(x/w,y/w)^Tw!=0(x,y,w)T=>(x/w,y/w)Tw!=0

则平移可以表示为:
Translation=[10tx01ty001][10tx01ty001]∗[xy1]=[x+txy+ty1](point)[10tx01ty001]∗[xy0]=[xy0](vector) Translation =\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}(point)\\ \begin{bmatrix} 1 & 0 & t_x\\ 0 & 1 & t_y\\ 0 & 0 & 1 \end{bmatrix}* \begin{bmatrix} x\\ y\\ 0 \end{bmatrix}= \begin{bmatrix} x\\ y\\ 0 \end{bmatrix}(vector) Translation=100010txty1100010txty1xy1=x+txy+ty1(point)100010txty1xy0=xy0(vector)

这样就可以将旋转,平移,错切等等放入同一个维度的矩阵去表示。

仿射变换(Affine Transformations)

仿射变换就是指线性变换与平移的组合:
[abcd]∗[xy]+[txty]=[ax+by+txcx+dy+ty] \begin{bmatrix} a & b \\ c & d \end{bmatrix}* \begin{bmatrix} x\\ y \end{bmatrix}+ \begin{bmatrix} t_x\\ t_y \end{bmatrix}= \begin{bmatrix} ax+by+t_x\\ cx+dy+t_y \end{bmatrix} [acbd][xy]+[txty]=[ax+by+txcx+dy+ty]
利用齐次坐标可以写成一个三维矩阵:
[abtxcdty001]∗[xy1]=[ax+by+txcx+dy+ty1](point) \begin{bmatrix} a & b & t_x\\ c & d & t_y\\ 0 & 0 & 1 \end{bmatrix}* \begin{bmatrix} x\\ y\\ 1 \end{bmatrix}= \begin{bmatrix} ax+by+t_x\\ cx+dy+t_y\\ 1 \end{bmatrix}(point) ac0bd0txty1xy1=ax+by+txcx+dy+ty1(point)

变换的组合与分解

对于任意多个变换可以表示成一个矩阵.试想对一个点或向量不断左乘变换矩阵,然后将变换矩阵结合就变成一个了:
(Scale∗……∗Rotation(ϕ))∗[xy1]=A∗[xy1] (Scale*……*Rotation(\phi))*\begin{bmatrix} x\\ y\\ 1 \end{bmatrix} = A*\begin{bmatrix} x\\ y\\ 1 \end{bmatrix} (ScaleRotation(ϕ))xy1=Axy1

对于变换的顺序:从右往左进行变换。矩阵乘法没有交换律,因此不能随意交换变换顺序。

变换的分解:

eg:绕给定点旋转?

先平移到原点,再旋转,再进行平移。(转换成已有的变换)

3D空间中的变换

使用齐次坐标:

2D向量:(x,y,z)T=>(x,y,z,0)T(x,y,z)^T=>(x,y,z,0)^T(x,y,z)T=>(x,y,z,0)T

2D点 :(x,y,z)T=>(x,y,z,1)T(x,y,z)^T=>(x,y,z,1)^T(x,y,z)T=>(x,y,z,1)T

对于3D点(x,y,w)T=>(x/w,y/w)Tw!=0(x,y,w)^T=>(x/w,y/w)^Tw!=0(x,y,w)T=>(x/w,y/w)Tw!=0

那么3D空间中的仿射变换为:
[abctxdeftyghitz0001]∗[xyz1]=[ax+by+cz+txdx+ey+fz+tygx+hy+iz+tz1](point) \begin{bmatrix} a & b & c&t_x\\ d & e & f &t_y\\ g & h & i& t_z\\ 0&0&0&1 \end{bmatrix}* \begin{bmatrix} x\\ y\\ z\\ 1 \end{bmatrix}= \begin{bmatrix} ax+by+cz+t_x\\ dx+ey+fz+t_y\\ gx+hy+iz+t_z\\ 1 \end{bmatrix}(point) adg0beh0cfi0txtytz1xyz1=ax+by+cz+txdx+ey+fz+tygx+hy+iz+tz1(point)
3D空间中变换与2D中的类似,但是旋转比较特殊,由此总结如下。

3D空间中的旋转

2D中的旋转表示为绕点旋转,而3D中的旋转表示为绕轴逆时针旋转。

绕x轴,y轴,z轴(坐标轴如下所示为右手坐标系):
Rx(ϕ)=[100tx0cos⁡ϕ−sin⁡ϕty0sin⁡ϕcos⁡ϕtz0001](绕x轴)Ry(ϕ)=[cos⁡ϕ0sin⁡ϕtx010ty−sin⁡ϕ0cos⁡ϕtz0001](绕y轴)Rz(ϕ)=[cos⁡ϕ−sin⁡ϕ0txsin⁡ϕcos⁡ϕ0ty001tz0001](绕z轴) R_x(\phi)=\begin{bmatrix} 1 & 0 & 0&t_x\\ 0 & \cos{\phi} & -\sin{\phi} &t_y\\ 0 & \sin{\phi} & \cos{\phi}& t_z\\ 0&0&0&1 \end{bmatrix}(绕x轴)\\ R_y(\phi)=\begin{bmatrix} \cos{\phi} &0& \sin\phi&t_x\\ 0 & 1 & 0& t_y\\ -\sin{\phi} & 0&\cos{\phi} &t_z\\ 0&0&0&1 \end{bmatrix}(绕y轴)\\ R_z(\phi)=\begin{bmatrix} \cos{\phi} & -\sin{\phi} &0&t_x\\ \sin{\phi} & \cos{\phi}&0& t_y\\ 0 & 0 & 1&t_z\\ 0&0&0&1 \end{bmatrix}(绕z轴) Rx(ϕ)=10000cosϕsinϕ00sinϕcosϕ0txtytz1(x)Ry(ϕ)=cosϕ0sinϕ00100sinϕ0cosϕ0txtytz1(y)Rz(ϕ)=cosϕsinϕ00sinϕcosϕ000010txtytz1(z)
在这里插入图片描述

对于绕任意轴的旋转,同样是可以转成绕x,y,z轴的旋转。

分解公式(Rodrigues’s Rotation Formula):
R(n,α)=cos⁡(α)I+(1−cos⁡α)nnT+sin⁡α[0−nznynz0−nx−nynx0] R(\pmb n,\alpha) =\cos(\alpha)\pmb I+(1-\cos \alpha)\pmb n\pmb n^T+\sin\pmb\alpha\begin{bmatrix} 0 & -\pmb n_z & \pmb n_y\\ \pmb n_z & 0 & -\pmb n_x\\ -\pmb n_y & \pmb n_x & 0\\ \end{bmatrix} R(nnn,α)=cos(α)III+(1cosα)nnnnnnT+sinααα0nnnznnnynnnz0nnnxnnnynnnx0
NOTE:默认n\pmb nnnn经过原点,对于轴来说需要指定起点,这里默认的起点为原点。如若遇到起点不在原点,可先平移到原点,在进行旋转,在平移回去。

四元数:主要是为了进行旋转的插值。

观测变换(view/camera transfrom)

介绍之前变换的目的是为了讨论虚拟相机的成像。给定一个3D场景,我们如何将其最终渲染到屏幕上(如何拍一张照片)。

  1. 站好位置(模型变换)
  2. 调好相机位置(视图变换,view/camera transfrom)
  3. 成像,拍照(投影变换,3维变2维,Projection (投影) transformation )

视图变换

如何定义相机的位置,与摆放?

  1. 位置。
  2. 朝向(看向的方向)
  3. 向上的方向。

通过这些可以确定一个相机。

为了方便起见。可以将相机变换到原点(位置),向上方向为y轴方向,看向z轴的负方向(朝向)。然后将所有其他物体进行同样的变换。

相机变换

为了将一个任意相机(位置,朝向,向上的方向分别为(e,g^,t^\pmb e,\hat g,\hat teee,g^,t^)变换到我们预想的位置。

  1. 将位置变换到原点e=>o\pmb e=>\pmb oeee=>ooo
  2. 将朝向变换到Z\pmb ZZZZ轴负方向g^=>−Z\hat g=>-\pmb Zg^=>ZZZ
  3. 将向上方向变换到Y\pmb YYYY轴的正方向t^=>Y\hat t=>Yt^=>Y

那么变换矩阵该怎么写呢?

  1. 平移2. 旋转

Mview=RviewTviewM_{view}=R_{view}T_{view}Mview=RviewTview

平移变换矩阵很好写:
Tview=[100−xe010−ye001−ze0001] T_{view}=\begin{bmatrix} 1& 0 &0&-x_{\pmb e}\\ 0 & 1&0& -y_{\pmb e}\\ 0 & 0 & 1&-z_{\pmb e}\\ 0&0&0&1 \end{bmatrix} Tview=100001000010xeeeyeeezeee1
旋转的做法:

  1. g^=>−Z,t^=>Y,g^×t^=>X\hat g=>-\pmb Z,\hat t=>Y,\hat g \times \hat t=>Xg^=>ZZZ,t^=>Y,g^×t^=>X(如下图所示)

对于旋转矩阵来说非常难写。但是从反向来(逆变换)看比较简单(旋转矩阵是正交矩阵,其对称矩阵便是它的逆矩阵)。

X=>g^×t^,Y=>t^,−Z^=>g\pmb X=>\hat g \times \hat t,\pmb Y=>\hat t,-\hat Z=>\pmb gXXX=>g^×t^,YYY=>t^,Z^=>ggg
Rview−1=[xg×txtx−g0yg×tyty−g0zg×tztz−g00001]Rview=[xg×tyg×tzg×t0xtytzt0x−gy−gz−g00001] R_{view}^{-1}=\begin{bmatrix} x_{g\times t}& x_t &x_{-g}&0\\ y_{g\times t} & y_t& y_{-g}&0\\ z_{g\times t} & z_t & z_{-g}&0\\ 0&0&0&1 \end{bmatrix}\\ R_{view}=\begin{bmatrix} x_{g\times t}& y_{g\times t} &z_{g\times t}&0\\ x_t & y_t&z_t& 0\\ x_{-g} & y_{-g}& z_{-g}&0\\ 0&0&0&1 \end{bmatrix} Rview1=xg×tyg×tzg×t0xtytzt0xgygzg00001Rview=xg×txtxg0yg×tytyg0zg×tztzg00001

在这里插入图片描述

对于view/camera transfrom,观测变换,由于相机与模型的相对位置关系,也叫做ModelView Transform。

投影变换

关于正交投影与透视投影的区别如下图。

在这里插入图片描述

透视投影符合近大远小的规律。

正交投影

定义一个空间的立方体([l,r]×[b,t]×[f,n][l, r] \times [b, t] \times [f, n][l,r]×[b,t]×[f,n]),(分别表示在x,y,z轴上的范围)。

把其映射到标准立方体(中心在原点,大小[−1,1]3[-1,1]^3[1,1]3),由于看向z轴的负方向,那么离相机越近,z值越大,越远越小。

则其变换矩阵:

首先平移中心,后缩放。则有:
Mproject=[2/(r−l)00002/(t−b)00002/(n−f)00001][100−(l+r)/2010−(b+t)/2001−(f+n)/20001]=[2(r−l)00−r+lr−l02(r−b)0−t+bt−b002(n−f)−n+fn−f0001] M_{project}=\left[ \begin{matrix} 2/(r-l) & 0 & 0 & 0\\ 0 & 2/(t-b) & 0 & 0 \\ 0 & 0 & 2/(n-f) & 0\\ 0 & 0 & 0 & 1\end{matrix}\right] \left[ \begin{matrix} 1 & 0 & 0 & -(l+r)/2\\ 0 & 1 & 0 & -(b+t)/2 \\ 0 & 0 & 1 & -(f+n)/2\\ 0 & 0 & 0 & 1\end{matrix} \right]\\ =\left[ \begin{matrix} \frac{2}{(r-l)} & 0 & 0 & -\frac{r+l}{r-l}\\ 0 & \frac{2}{(r-b)} & 0 & -\frac{t+b}{t-b} \\ 0 & 0 & \frac{2}{(n-f)} & -\frac{n+f}{n-f}\\ 0 & 0 & 0 & 1\end{matrix}\right] Mproject=2/(rl)00002/(tb)00002/(nf)00001100001000010(l+r)/2(b+t)/2(f+n)/21=(rl)20000(rb)20000(nf)20rlr+ltbt+bnfn+f1
物体确实会被拉伸(后续会做视口变换)。

透视投影

  1. 近大远小
  2. 平行线不再平行

如图所示为了更好的得到变换矩阵,可以先压缩放,经四棱台压缩成立方体,后利用正交投影来做。

  1. 近平面不变。
  2. z值不变。
  3. 任意切面上的中心点位置不变。

在这里插入图片描述

基于几个假设来推导透视投影的矩阵。

近平面上的点映射到立方体上,坐标不变。

远平面上的点映射到立方体上,z值不变,中心点坐标不变。

透视投影的矩阵推导

压缩

利用相似三角形,如图所示,对于一个初始点(x,y,z)(x,y,z)(x,y,z)将其映射到立方体上。有如下相似三角形。

则变换后的y′=nzyy^{'}=\frac{n}zyy=zny。同理x′=nzxx^{'}=\frac{n}zxx=znx

那么对于任意(x,y,z)(x,y,z)(x,y,z)在其次坐标下有:
[xyz1]=>[x′y′unkown1]=[nzxnzyunkown1]=[nxnyunkownz]齐次坐标下的点 \left[ \begin{matrix} x\\ y \\ z \\ 1 \end{matrix}\right] =>\left[ \begin{matrix} x^{'}\\ y^{'} \\ \text{unkown} \\ 1 \end{matrix}\right]= \left[ \begin{matrix} \frac{n}zx\\ \frac{n}zy \\ \text{unkown} \\ 1 \end{matrix}\right]= \left[ \begin{matrix} nx\\ ny \\ \text{unkown} \\ z \end{matrix}\right]\text{齐次坐标下的点} xyz1=>xyunkown1=znxznyunkown1=nxnyunkownz齐次坐标下的点
那么可以得到构造矩阵:
[n0000n00????0010]∗[xyz1]=[nxnyunkownz] \left[ \begin{matrix} n & 0 & 0 & 0\\ 0 & n & 0 & 0\\ ? & ? & ? & ?\\ 0 & 0 & 1 & 0\end{matrix} \right]*\left[ \begin{matrix} x\\ y \\ z \\ 1 \end{matrix}\right]= \left[ \begin{matrix} nx\\ ny \\ \text{unkown} \\ z \end{matrix}\right] n000n0001000xyz1=nxnyunkownz

为了得到第三行的元素:利用之前的假设

近平面上的点映射到立方体上,坐标不变。

远平面上的点映射到立方体上,z值不变,中心点坐标不变。

则有:
[n0000n00ABCD0010]∗[x′y′n1]=[nx′ny′n2n]==[x′y′n1][n0000n00ABCD0010]∗[centerxcenteryf1]=[f∗centerxf∗centeryf2f]Ax+By+Cn+D=n2A∗centerx+B∗centery+Cf+D=f \left[ \begin{matrix} n & 0 & 0 & 0\\ 0 & n & 0 & 0\\ A & B & C & D\\ 0 & 0 & 1 & 0\end{matrix} \right]*\left[ \begin{matrix} x^{'}\\ y^{'} \\ n \\ 1 \end{matrix}\right]= \left[ \begin{matrix} nx^{'}\\ ny^{'} \\ n^2 \\ n \end{matrix}\right]== \left[ \begin{matrix} x^{'}\\ y^{'} \\ n \\ 1 \end{matrix}\right]\\ \left[ \begin{matrix} n & 0 & 0 & 0\\ 0 & n & 0 & 0\\ A & B & C & D\\ 0 & 0 & 1 & 0\end{matrix} \right]*\left[ \begin{matrix} center_x\\ center_y \\ f \\ 1 \end{matrix}\right]= \left[ \begin{matrix} f*center_x\\ f*center_y\\ f^2 \\ f \end{matrix}\right]\\ Ax+By+Cn+D = n^2\\ A*center_x+B*center_y+Cf+D =f n0A00nB000C100D0xyn1=nxnyn2n==xyn1n0A00nB000C100D0centerxcenteryf1=fcenterxfcenteryf2fAx+By+Cn+D=n2Acenterx+Bcentery+Cf+D=f

对于任意近平面的任意(x,y)都有Ax+By+Cn+D=nAx+By+Cn+D = nAx+By+Cn+D=n,因此A=0,B=0A=0,B=0A=0,B=0.

因此联立Cn+D=n2,Cf+D=f2Cn+D=n^2,Cf+D=f^2Cn+D=n2,Cf+D=f2

则可以解得:C=n+f,D=−nfC=n+f,D=-nfC=n+f,D=nf

因此可以得到
Mpresp−>ortho=[n0000n0000n+f−nf0010]Mpresp=MorthoMpresp−>ortho M_{presp->ortho}=\left[ \begin{matrix} n & 0 & 0 & 0\\ 0 & n & 0 & 0\\ 0& 0 & n+f & -nf\\ 0 & 0 & 1 & 0\end{matrix} \right]\\ M_{presp}=M_{ortho}M_{presp->ortho} Mpresp>ortho=n0000n0000n+f100nf0Mpresp=MorthoMpresp>ortho

Reference

  1. https://www.bilibili.com/video/BV1X7411F744?t=4503&p=4
  2. https://sites.cs.ucsb.edu/~lingqi/teaching/games101.html
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值