原文链接:http://blog.csdn.net/magiczyj/article/details/51316480
In English,Affine means 仿射,Transform means 变换,so,you know it.
来看一个常量
/* The identity transform: [ 1 0 0 1 0 0 ]. */
CG_EXTERN const CGAffineTransform CGAffineTransformIdentity
CG_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
一般形式
CG_EXTERN CGAffineTransform CGAffineTransformMake(CGFloat a, CGFloat b,
CGFloat c, CGFloat d, CGFloat tx, CGFloat ty)
CG_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
仿射变换的原理:基于高数的矩阵变换
计算规律:C = A的行✖️B的每一列
矩阵A = [ ]
1 1
2 0
[ ]
矩阵B = [ ]
0 2 3
1 1 2
[ ]
矩阵C = A * B = [ ]
1 3 5
0 4 6
[ ]
仿射变换的矩阵计算
self.label.transform = CGAffineTransformMake(<#CGFloat a#>, <#CGFloat b#>, <#CGFloat c#>, <#CGFloat d#>, <#CGFloat tx#>, <#CGFloat ty#>)
对应矩阵如下:
B = [ ]
a b 0
c d 0
tx ty 1
[ ]
由上面的矩阵变换的基础计算可以得到平面上任意一点设为A =【x y 1】变换后的计算公式为
C = [ (a*x+c*y+tx) (b*x+d*y+ty) (1) ]
由A经过矩阵B变换后得到的C进行比较,得出:
x' = a*x + c*y + tx
y' = b*x + d*y + ty
由上面这个公式随便举个例子,我们让a、d=1 其余均为0 得到
x' = x
y' = y
这就是 CGAffineTransformIdentity (未发生变换)
一般公式推导平移
设a,d=1 c,b = 0
由
x' = a*x + c*y + tx
y' = b*x + d*y + ty
得:
x' = x + tx
y' = y + ty
可以知道tx代表视图沿X轴方向的位移,ty代表视图沿Y轴方向的位移
所以使用一般公式实现视图沿X轴平移50如下实现:
CGAffineTransformMake(1,0,0,1,50,0)
一般公式推导缩放
设 c,b,tx,ty = 0
由
x' = a*x + c*y + tx
y' = b*x + d*y + ty
得:
x' = a*x
y' = d*y
一般公式推导剪切
设 a,d = 1 tx,ty = 0
由
x' = a*x + c*y + tx
y' = b*x + d*y + ty
得
x' = x + cy
y' = y + bx
一般公式推导旋转
//仿射旋转矩阵
[ ]
cosa sina 0
-sina cosa 0
0 0 1
[ ]
CGAffineTransformMake(CGFloat( cos(M_PI_4) ), CGFloat( sin(M_PI_4) ), -CGFloat( sin(M_PI_4) ), CGFloat( cos(M_PI_4) ), 0, 0)
其他的常用方法:
//检查是否有做过仿射效果
CGAffineTransformIsIdentity(transform)
//检查2个仿射效果是否相同
CGAffineTransformEqualToTransform(transform1,transform2)
//仿射效果反转(反效果,比如原来扩大,就变成缩小)
CGAffineTransformInvert(transform)
在众多动画中,仿射动画确实功能强大,对一些系统无法改变frame的控件,我们都可以通过它来改变。
在很多时候,我们在使用UIView动画实现控件大小改变的时候,如果frame设置实现不了动画效果,我们可以使用仿射变化达到目的。
使用仿射变化首先应该明白layer层的一个属性—-锚点
默认仿射变化的锚点是(0.5,0.5),以前做过仪表盘动画的都知道在视图旋转时我们要调整锚点,否则无法凸显那是个指针。。。,关于锚点,就不多做解释了。
使用锚点的注意点如下:
1、锚点决定了动画的方向,也就是说视图选定的锚点不同时,动画效果是不一样的,依照情况定。
2、在动画开始前,应当已经设置好视图的锚点。
3、在设置视图的frame之前,应当设置好视图的锚点。