仿射变换
网上关于仿射变换的文章也有一些,有许多文章只讲解了矩阵中的每个值的作用,而没有解释为什么.所以自己也推导一边,方便写这篇博客,也巩固了一下相关知识.
2d仿射矩阵
让我们来看看定义CGAffineTransform(其他语言同样可以适用)
struct CGAffineTransform {
CGFloat a, b, c, d;
CGFloat tx, ty;
};
在这里定义成了结构体,要模拟的其实是3*3的矩阵,我在这里建立,至于为什么结构体里只有6个值,等下便可以明白。
[m11 m12 m13]
[m21 m22 m23]
[m31 m32 m33]
变换过程
[m11 m12 m13]
[x y 1]* [m21 m22 m23] = [x*m11+y*m21+m31 x*m12+y*m22+m32 x*m13+y*m23+m33]
[m31 m32 m33]
可以看到已经过变幻之后
x映射到xm11+ym21+m31
y映射到xm12+ym22+m32
移动
令m11=1 m21=0 那么 x映射到 x+m31点 所以m31就是CGAffineTransform中的tx.同理等到m32是ty.
缩放
令m21=0,m31=0 那么x映射到x*m11点 这样便实现了缩放,当m11大于1时为方法,反之缩小.
旋转
旋转相对而言比较复杂一些,需要三角函数的知识.也是很多博客中没有介绍的部分.我们进行一下简单的推倒.
我们对任意的单位向量进行旋转,假设(x1,y1)为旋转前的单位向量.其与x正轴的夹脚为theta.那么该单位向量可以表示为(cos(theta),sin(theta))
我们对其逆时针旋转△theta,那么现在该单位向量可以表示为(cos(theta+△theta),sin(theta+△theta))
运用三角函数可以得到旋转后的向量为(cos(theta)cos(△theta)-sin(theta)sin(△theta),sin(theta)cos(△theta)+cos(theta)sin(△theta))
也就是x1=cos(theta)映射到cos(theta)cos(△theta)-sin(theta)sin(△theta)=x1cos(△theta)-y1sin(△theta);
所以只需要令
m11=cos(△theta),m21=-sin(△theta) ,m31=0
m12 =sin(△theta),m22 = cos(△theta),m32 =0
这样就是旋转
3d变换
3d变换的推倒思路一致,这里不再冗余,不过在3d旋转中要用到欧拉角的概念,我这里直接引用一张图片来表示
这张图表现了3d旋转的矩阵值。如果你把某些值做一个替换,就会发现其退化为2d矩阵。其实就是2d变化是个3d变化的特例。留给读者自己思考