iOS开发:仿射变换CGAffineTransform原理与详解

UIView有CGAffineTransform类型的属性transform,它是定义在二维空间上完成View的平移,旋转,缩放等效果的实现。

初始化: CGAffineTransform  transform = CGAffineTransformIdentity;

CGAffineTransformIdentity是系统提供的一个常量,/* The identity transform: [ 1 0 0 1 0 0 ]. */(和原图一样的transform);

 CGAffineTransform transform  = CGAffineTransformMake(CGFloat a,CGFloat b,

CGFloat c,CGFloa td,CGFloat tx,CGFloat ty)

我们来解释下这里面参数的作用和变换的效果;

下面是原始的(默认的)transform


UIView默认的

参数结构

人后我们再来看它的计算公式:3 X 3矩阵合成得到(x`,y`,1)


(x`,y`,1)公式

矩阵算法公式:


算法公式

相信大家有所了解,我是懂了点点(数学是历史老师教的),看不到直观的东西。

接下来我们我们新建工程,在widow上建立两个同样大小位置相同的View,第一个为沙色,第二个是浅海蓝色,我修改第二个View的transform中a的值为0.2:CGAffineTransformMake(0.2,0,0,1,0,0);

图一是没有改变的原图,图二是改变之后的View,很明显的差异


原图

View2的transform变化后的图

我用3秒动画完成变换,发现它是两边开始往中间缩小,打印View的frame原来的{{100,100},{100,100}}变成了{{140,100},{20,100}}。我们来计算下是不是根据公式计算的。

根据变换的transform我们知道 a = 0.2 , b = 0 , c = 0 , d = 1 , t.x = 0 , t.y = 0;

                                                         x = 100 ,  y = 100

x` = ax + cy + t.x = 0.2 * 100 + 0 * 100 + 0 = 20

y` = bx + dy + t.y = 0 * 100 + 1 * 100 + 0 = 100

结合上面的图和下面的计算,瞬间明白了这是x按照a值进行了比例缩放,y按照d的值进行比列缩放,最重要的是缩放的过程中View的point(中心点)是不会改变的。

接着对b,c,t.x ,ty,进行深度研究发现:

x会跟着c的值进行拉伸(View的宽度是跟着改变),y会跟着b的值进行拉伸(View的高度跟着改变),要注意到的是c和b的值改变不会影响到View的point(center中心点)的改变。这是个很有意思的两个参数。

x会跟着t.x进行x做表平移,y会跟着t.y进行平移。这里的point(center)是跟着变换的。

下面是Apple整合的transform

平移 :

①根据本身的transform进行平移   CGAffineTransformMakeTranslation(CGFloat tx,CGFloat ty)

②根据本身的transform后者另外的transform进行平移CGAffineTransformTranslate(CGAffineTransform t,CGFloat tx,CGFloat ty)

缩放 

①根据本身的transform进行缩放 

CGAffineTransformMakeScale(CGFloat sx,CGFloat sy)

②根据本身的transform后者另外的transform进行缩放

 CGAffineTransformScale(CGAffineTransform t,CGFloat sx,CGFloat sy)

旋转 :

① 根据本身的transform进行旋转

 CGAffineTransformMakeRotation(CGFloat angle) (angle 旋转的角度)

②根据本身的transform后者另外的transform进行旋转

CGAffineTransformRotate(CGAffineTransform t,CGFloat angle)

反转:

CGAffineTransformInvert(CGAffineTransform t)                                                                                           

合并

CGAffineTransformConcat(CGAffineTransform t1,CGAffineTransform t2)       

两个transform合并起来

倾斜:

这个使我们自己定义

-(CGAffineTransform) CGAffineTransformMakeShear(CGFloat x,CGFloat y)

{   CGAffineTransform transform = CGAffineTransformIdentity;

transform.c= -x;

transform.b= y;

returntransform;   }

layer.affineTransform = CGAffineTransformMakeShear(1,0);

评测:

①Bool CGAffineTransformIsIdentity(CGAffineTransform t)                   

 查看是不是默认的transform

②bool CGAffineTransformEqualToTransform(CGAffineTransform t1,CGAffineTransform t2)  

 比较两个transform是否相等

仿射矩阵应用:

①CGPointApplyAffineTransform(CGPoint point,CGAffineTransform t)  得到新的中心CGPoint

②CGSizeApplyAffineTransform(CGSize size,CGAffineTransform t)          得到新的size CGSize

③CGRectApplyAffineTransform(CGRect rect,CGAffineTransform t)        得到新的rect CGRect

放射矩阵一个常用的情形就是根据用户的手势来相应的改变视图的变换

UIPanGestureRecognizer                   位移

UIPinchGestureRecognizer                缩放

UIRotationGestureRecognizer          旋转

苹果官方的建议,要多次使用transform,最好是初始化一个CGAffineTransform,进行多次操作。

Note that you do not typically need to create affine transforms directly. If you want only to draw an object that is scaled or rotated, for example, it is not necessary to construct an affine transform to do so. The most direct way to manipulate your drawing—whether by movement, scaling, or rotation—is to call the functionsCGContextTranslateCTM,CGContextScaleCTM, orCGContextRotateCTM, respectively. You should generally only create an affine transform if you want to reuse it later.(原谅我英语不够好。)

转载地址:http://www.jianshu.com/p/6c09d138b31d

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值