A和B两个矩阵相乘,就要A的列数等于B的行数才有相乘的意义,相乘结果是一个矩阵C,C的行数和A的行数相等,C的列数和B的列数相等,C的每个元素值为A对应的行与B对应的列的元素乘积的和:
CGAffineTransform 的结构如下:
struct CGAffineTransform
{
CGFloat a, b, c, d;
CGFloat tx, ty;
};
为了把二维图形的变换统一在一个坐标系里,引入了齐次坐标的概念,即把一个图形用一个三维矩阵表示,其中第三列总是(0,0,1),用来作为坐标系的标准。
CGAffineTransform表示的是这样一个矩阵
因为最后一列总是是(0,0,1),所以有用的信息就是前面两列。
运算原理:假设原坐标设为(X,Y,1),变换后的坐标为(xx,yy,1),那么原坐标、坐标变换以及变换后的坐标对应矩阵的关系应该是:
|a b 0|
[X,Y, 1] x |c d 0| = [xx,yy,1];
|tx ty 1|
根据矩阵计算方法,左边矩阵相乘的实际结果是:[aX + cY + tx , bX + dY + ty , 1];所以对比出来原坐标 X 经过CGAffineTransform变换之后等于 aX + cY + tx,原坐标Y经过CGAffineTransform变换之后等于 bX + dY + ty。我们对比一下可知:
第一种:设a=d=1, b=c=0.
[aX + cY + tx, bX + dY + ty, 1] = [X + tx, Y + ty, 1];即X + tx = xx;Y + ty = yy;
可见,这个时候,坐标是按照向量(tx,ty)进行平移,其实这也就是函数
CGAffineTransform CGAffineMakeTranslation(CGFloat tx,CGFloat ty)的计算原理。
第二种:设b=c=tx=ty=0.
[aX + cY + tx, bX + dY + ty, 1] = [aX , dY, 1];即aX = xx;dY, = yy;
可见,这个时候,坐标X按照a进行缩放,Y按照d进行缩放,a,d就是X,Y的比例系数,其实这也就是函数
CGAffineTransform CGAffineTransformMakeScale(CGFloat sx, CGFloat sy)的计算原理。a对应于sx,d对应于sy。
第三种:设tx=ty=0,a=cos?,b=sin?,c=-sin?,d=cos?。
[aX + cY + tx , bX + dY + ty, 1] = [Xcos? - Ysin?, Xsin? + Ycos?, 1] ;即Xcos? - Ysin? =xx; Xsin? + Ycos? = yy;
可见,这个时候,?就是旋转的角度,逆时针为正,顺时针为负。其实这也就是函数
CGAffineTransform CGAffineTransformMakeRotation(CGFloat angle)的计算原理。angle即?的弧度表示。
常量 CGAffineTransformIdentity const CGAffineTransformCGAffineTransformIdentity;
这个就是没有变换的最初的样子。
创建一个仿射矩阵,用一下几个方法创建的仿射矩阵,多次作用于一个对象,效果不会累加,即每次只会以原始位置进行放射变换。
- CGAffineTransformMake(CGFloat a, CGFloat b, CGFloat c, CGFloat d, CGFloat tx, CGFloat ty) 直接赋值来创建
- CGAffineTransformMakeTranslation(CGFloat tx,CGFloat ty) 设置偏移
- CGAffineTransformMakeRotation(CGFloat angle) 设置角度来生成矩阵
- CGAffineTransformMakeScale(CGFloat sx, CGFloat sy) 通过设置缩放系数生成矩阵
改变已经存在的放射矩阵,即会在上一次的放射矩阵的基础上累加
- CGAffineTransformTranslate(CGAffineTransform t,CGFloat tx, CGFloat ty) 原始的放射矩阵基础上加上偏移,生成新的放射矩阵
- CGAffineTransformScale(CGAffineTransform t,CGFloat sx, CGFloat sy)原始的放射矩阵基础上加上缩放,生成新的放射矩阵
- CGAffineTransformRotate(CGAffineTransform t,CGFloat angle)原始的放射矩阵基础上加上旋转,生成新的放射矩阵
- CGAffineTransformInvert (CGAffineTransform t)原始的放射矩阵进行反向得到新的放射矩阵,比如(x,y)通过矩阵t得到了(x’,y’)那么通过这个函数生成的t’作用与(x’,y’)就能得到原始的(x,y)
- CGAffineTransformConcat(CGAffineTransform t1,CGAffineTransform t2) 通过两个已经存在的放射矩阵生成一个新的矩阵t‘ = t1 * t2
应用仿射矩阵
- CGPointApplyAffineTransform 得到新的点
- CGSizeApplyAffineTransform 得到新的size
- CGRectApplyAffineTransform 得到新的rect
评测矩阵
- CGAffineTransformIsIdentity 是否是CGAffineTransformIsIdentity
- CGAffineTransformEqualToTransform 看两个矩阵是否相等