Computer Graphics note(1):变换
Games101清新脱俗,可惜没赶上直播。
官网:http://games-cn.org/intro-graphics/
结合食用:Fundamentals of Computer Graphics (3rd Edition) or (2nd Edition)
一.2D变换
对于能写成X′=MX形式的变换,称为线性变换(Linear Transforms),其中M为变换矩阵。
1.Scale(缩放)
基本的缩放就是沿着坐标轴进行的缩放,而对于xy轴任意比例缩放sx,sy而言,其数学形式如下:
{x′=sx∗xy′=sy∗y
转换为矩阵形式((x,y)T左边的矩阵为变换矩阵)如下:
[x′y′]=[sx00sy][xy]
例如下图为沿着xy轴都缩放0.5:

水平镜像也属于缩放操作,即sx=−1,sy=1,其矩阵表示如下:
[x′y′]=[−1001][xy]
2.Shear(切变)
切变只变化一边,如下图所示:

可见,上面是变化了x轴,其矩阵形式如下:
[x′y′]=[1a01][xy]
同理,对于变化y轴,其矩阵形式如下:
[x′y′]=[10a1][xy]
3.Rotate(旋转)
对于旋转而言,前提是默认绕原点旋转,方向为逆时针,旋转角为弧度制。x轴转转向y轴。
对于一个向量a,其与x轴夹角为α假设要将其旋转角度φ得到向量b,如下图所示(图来源:Fundamentals of Computer Graphics (3rd Edition) 6.1.3Rotation):

其旋转矩阵如下:
R(φ)[cosφ−sinφsinφcosφ]
推导过程1如下(来自Fundamentals of Computer Graphics (3rd Edition) 6.1.3Rotation):
假设向量a的长度为r,则有
{xa=rcosαya=rsinα
而b是a旋转得到的,所以长度相同,而其旋转角度为(α+φ),则有
{xb=rcos(α+φ)=rcosαcosφ−rsinαsinφyb=rsin(α+φ)=rsinαcosφ+rcosαsinφ
将上面的式子带入下面的式子可以得到如下结果:
{xb=xacosφ−yasinφyb=yacosφ+xasinφ
所以最终的旋转矩阵如下:
R(φ)[cosφ−sinφsinφcosφ]
推导过程2(课程提及,辅助理解记忆)如下

考虑旋转矩阵对于任意点都适用,所以考虑几个特殊点的转换:(1,0)−>(cosθ,sinθ),(0,1)−>(cosθ,−sinθ)。所以有下列关系:
⎧⎪
⎪
⎪
⎪
⎪
⎪⎨⎪
⎪
⎪
⎪
⎪
⎪⎩[cosθsinθ]=[ABCD][10][−sinθcosθ]=[ABCD][01]
从中可以得到如下结果,即为所求:
⎧⎪
⎪⎨⎪
⎪⎩A=cosθC=sinθB=−sinθD=cosθ
旋转矩阵的性质
考虑旋转R(−φ),会发现等于RTφ,如下所示:
R(−φ)[cosφ−sinφsinφcosφ]=RTφ
而从定义上看,R(−φ)=R−1φ,所以可以得到R−1φ=RTφ,即旋转矩阵的逆等于其转置矩阵,也就是说旋转矩阵为正交矩阵(数学意义)。
4.Translation(平移) & 齐次坐标
对于平移而言,即使考虑只有平移的情况,我们也只能写成如下形式:
对于平移:
{x′=x+txy′=y+ty
其矩阵形式如下:
[x′y′]=[1001][xy]+[txty]
为了让平移和上面的线性转换统一,引入齐次坐标。对于2D变换,增加一个维度w,此时规定点和向量的齐次坐标表示如下:
point=(x,y,1)Tvector=(x,y,0)T
即对于齐次坐标而言,(x,y,w)T(w!=0)表示的点即为(xw,yw,1)T。
则对于平移而言,其矩阵形式表示变为:
⎡⎢⎣x′y′w′⎤⎥⎦=⎡⎢⎣10tx01ty001⎤⎥⎦⎡⎢⎣xy1⎤⎥⎦=⎡⎢⎣x+txy+ty1⎤⎥⎦
这样一来形式就得到统一,并且使用齐次坐标还能保证以下操作的正确性:
vector+vector=vector;point−point=vector;point+vector=point;
而对于point+point原本是无意义的,但是在齐次坐标下也能引申出其他意义,即两点相加为其中点,推导过程如下:
⎛⎜⎝x1y11⎞⎟⎠+⎛⎜⎝x2y21⎞⎟⎠=⎛⎜⎝x1+x2y1+y22⎞⎟⎠=⎛⎜
⎜⎝x1+x22y1+y221⎞⎟
⎟⎠
仿射变换 = 线性变换 +平移,即为
[x′y′]=[abcd][xy]+[txty]
使用齐次坐标表示如下:
⎡⎢⎣x′y′1⎤⎥⎦=⎡⎢⎣abtxcdty001⎤⎥⎦⎡⎢⎣xy1⎤⎥⎦
上面两者是等价的,所以仿射变换是先进行线性变换然后再进行的平移。
1.变换矩阵的结构性质
值得一提的是,当表示的是2D仿射变换的时候,上面的变换矩阵才有如下性质:
- 最后一行为001
- 最后一列的头两个数tx,ty必然表示平移
- 左上角四个数(abcd)表示线性变换
2.齐次坐标下的变换矩阵
Scale:
S(Sx,Sy)=⎡⎢⎣sx000sy0001⎤⎥⎦
Rotation:
R(φ)=⎡⎢⎣cosφ−sinφ0sinφcosφ0001⎤⎥⎦
Translation:
T(tx,ty)=⎡⎢⎣10tx01ty001⎤⎥⎦
三.其他变换
逆变换即为原变换的相反操作,逆变换对应的变换矩阵即在数学意义上的逆矩阵,如下图中M−1即为逆变换对应的变换矩阵,且逆矩阵有个基本性质,即MM−1=I,其中I为单位矩阵。

以下图为例子,假如想要从左边变换到右边的话,可以考虑的方式有先旋转再平移,或者先平移再旋转。

两种方式结果如下:

很明显,需要先旋转再平移,上面的变换过程用矩阵表示如下:
T1,0⋅R45⎡⎢⎣xy1⎤⎥⎦=⎡⎢⎣101010001⎤⎥⎦⎡⎢⎣cos45−sin450sin45cos450001⎤⎥⎦⎡⎢⎣xy1⎤⎥⎦
结论
- 以变换的顺序很重要,顺序不同结果也就不同。
- .变换矩阵应用的顺序是从右到左的。
上述结论可以推广,即当有N个变换矩阵A1 An应用时,也是从右到左进行应用,同时因为矩阵满足结合律,所以我们可以先将前面的所有变换矩阵相乘(Ar=An⋅⋅⋅A2A1),然后再应用,结果是不变的。如下:
An⋅⋅⋅A2A1⎡⎢⎣xy1⎤⎥⎦=Ar⎡⎢⎣xy1⎤⎥⎦
值得一提的是由于矩阵都是3X3,所以即使前面的相乘,得到的矩阵Ar仍然是3X3,也就是说一个矩阵也可以表示极为复杂的变换。
同时考虑仿射变换的性质,上面先旋转再平移也可以写成如下形式,结果不变:
T1,0⋅R45⎡⎢⎣xy1⎤⎥⎦=⎡⎢⎣cos45−sin451sin45cos450001⎤⎥⎦⎡⎢⎣xy1⎤⎥⎦
变换的分解有多种多样,有时候不能一次性写出旋转矩阵,就可以将其分解,逐步应用变换矩阵来达到同样的效果。
例如考虑绕任意点c进行旋转,可以先将旋转中心移动到原点进行旋转之后再将旋转中心移动到c点。如下图所示:

其矩阵表示如下,应用过程从右到左:
T(c)⋅R(α)⋅T(−c)
四.3D变换
1.前提(右手系)
以下变换考虑的都是右手系(参考右手螺旋定则,四指弯曲方向为x旋转到y方向,大拇指方向为z方向)。
2.齐次坐标表示
类比2D中引入齐次坐标的原因,3D中的平移也不能直接写成,所以对于3D变换,增加一个维度w,此时规定点和向量的齐次坐标表示如下:
point=(x,y,z,1)Tvector=(x,y,z,0)T
同样的有对于齐次坐标而言,(x,y,z,w)T(w!=0)表示的点即为(xw,yw,zw,1)T。
矩阵描述3D中的仿射变换如下:
⎡⎢
⎢
⎢⎣x′y′z′1⎤⎥
⎥
⎥⎦=⎡⎢
⎢
⎢
⎢⎣abctxdeftyghitz0001⎤⎥
⎥
⎥
⎥⎦⎡⎢
⎢
⎢⎣xyz1⎤⎥
⎥
⎥⎦
3.变换矩阵的结构性质
和2D中一样,当表示的是3D仿射变换的时候,上面的变换矩阵才有如下性质:
- 最后一行为0001
- 最后一列的头两个数tx,ty,tz必然表示平移
- 左上角9个数⎛⎜⎝abcdefghi⎞⎟⎠表示线性变换
4.齐次坐标下的变换矩阵
3D下和2D下的缩放和平移类似,但是旋转有些不同,
Scale:
S(Sx,Sy)=⎡⎢
⎢
⎢
⎢⎣sx0000sy0000sz00001⎤⎥
⎥
⎥
⎥⎦
Translation:
T(tx,ty)=⎡⎢
⎢
⎢
⎢⎣100tx010ty001tz0001⎤⎥
⎥
⎥
⎥⎦
Rotation
先考虑只绕一轴进行旋转的情况(绕谁谁不变),如下:
Rx(α)=⎡⎢
⎢
⎢⎣10000cosα−sinα00sinαcosα00001⎤⎥
⎥
⎥⎦Ry(α)=⎡⎢
⎢
⎢⎣cosα0sinα00100−sinα0cosα00001⎤⎥
⎥
⎥⎦Rz(α)=⎡⎢
⎢
⎢⎣cosα−sinα00sinαcosα0000100001⎤⎥
⎥
⎥⎦
这里绕着y轴有所不同,这是因为我们使用的右手系,旋转方向默认逆时针的情况下,绕y轴,是z转向x方向,而矩阵定义的旋转顺序为xyz,即为x->y,y->z,x->z。

接下来简单总结一下一般情况绕任意轴下的3D旋转。
普通的3D旋转可以将其分解到绕xyz旋转,然后推导其公式(Rodrigues′RotationFormula)如下,其中nn为旋转轴,α为旋转角,I为单位矩阵,这里默认沿着nn旋转时,该轴是过原点的:
R(nn,α)=cos(α)II+(1−cos(α))nnnnT+sin(α)⎛⎜⎝0−nznynz0−nz−nynx0⎞⎟⎠
最右边的是向量叉积的矩阵形式。推导略。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架