一个任意的仿射变换都能表示为 乘以一个矩阵 (线性变换) 接着再 加上一个向量 (平移)。 我们能够用仿射变换来表示:
我们通常使用 2 x 3 矩阵来表示仿射变换(以下需要一些线性代数的知识)。
用矩阵A和B对二维向量X做变换,那上式也可表示为
单位矩阵,主对角线为1,其他都为0的矩阵
struct CGAffineTransform { CGFloat a, b, c, d; CGFloat tx, ty; };
虽然结构体中只有a
,b
,c
,d
,tx
,ty
6个参数,但其实还有3个固定的参数[0,0,1]来组成3x3的矩阵。
PS:anchorPoint定义了应用变换的坐标系的原点。
仿射变换表示为一个3x3的矩阵如下:
对于一个CGPoint
(x, y), 经过以上仿射变换后为(x’, y’),可表示为
即公式(1):
/* The identity transform: [ 1 0 0 1 0 0 ]. */ CG_EXTERN const CGAffineTransform CGAffineTransformIdentity CG_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
identity矩阵可以表示为
代入公式(1),的得到
整理后得到
identity仿射矩阵计算后的坐标也就是坐标自己本身。
/* Return a transform which translates by `(tx, ty)': t' = [ 1 0 0 1 tx ty ] */ CG_EXTERN CGAffineTransform CGAffineTransformMakeTranslation(CGFloat tx, CGFloat ty) CG_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
CGAffineTransformMakeTranslation
是一个进行平移的方法,根据注释得到的矩阵为
代入公式(1),的得到
整理后得到
CGAffineTransformMakeTranslation
也就是所对原来坐标进行一个平移的操作,在x轴方向上移动tx,在y轴方向上移动ty。
/* Return a transform which scales by `(sx, sy)': t' = [ sx 0 0 sy 0 0 ] */ CG_EXTERN CGAffineTransform CGAffineTransformMakeScale(CGFloat sx, CGFloat sy) CG_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
CGAffineTransformMakeScale
是一个进行缩放的方法,根据注释得到的矩阵为
代入公式(1),的得到
整理后得到
CGAffineTransformMakeScale
方法在x轴上缩放sx,在y轴上缩放sx
/* Return a transform which rotates by `angle' radians: t' = [ cos(angle) sin(angle) -sin(angle) cos(angle) 0 0 ] */ CG_EXTERN CGAffineTransform CGAffineTransformMakeRotation(CGFloat angle) CG_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
CGAffineTransformMakeRotation
是一个进行旋转的方法,根据注释得到的矩阵为
代入公式(1),的得到
整理后得到
两边都平方,得到
两式左右都相加得到
化简后得到
直接就是圆的方程,这只是证明x’ 与 y’在变换后任然在与x 和 y 在以(0,0)为圆心的圆上。
根据上图用三角函数表示公式(1)
CGAffineTransformMakeRotation
方法用来计算出原来点(x,y)旋转α°之后的(x',y'),即将原来的旋转α°。也就是将view或者layer以anchorPoint为中心点旋转α°