美文网首页iOSiOS-行知iOS大牛修炼之路
iOS 仿射变换CGAffineTransform详解

iOS 仿射变换CGAffineTransform详解

作者: 燃烧的大叔 | 来源:发表于2015-04-30 17:03 被阅读18959次

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.(原谅我英语不够好。)

Good lucky , every one!五一快乐!

相关文章

网友评论

  • _烩面_:不错,适合初学者!
  • 云之彼岸君:一个UIView底部固定,顶部向上拉伸的动画该怎么做?
  • 2537524b7b0f: [UIView animateWithDuration:ANI_DURATION animations:^{

    CGAffineTransform tranform = CGAffineTransformMakeRotation(M_PI);
    self.benzImageView.transform = CGAffineTransformTranslate(tranform, 0, -100);

    } ];
    大神大神,怎么解释图片向上移动?:smile:
  • 涩涩涩涩:我想先移动,再点击缩放,但是缩放后会回到移动前的位置,这个问题可以解决么?
    绍清_shao:可以解决啊
    涩涩涩涩:@燃烧的大叔 嗯,我试一下
    燃烧的大叔:@涩涩涩涩 你用移动后的transform试试
  • 青青河边草2041:这个方法CGAffineTransformInvert(CGAffineTransform t)理解有误吧。。。。是反转不是恢复😓。。。
    燃烧的大叔:@青青河边草2041 谢谢,我晚上看下。

本文标题:iOS 仿射变换CGAffineTransform详解

本文链接:https://www.haomeiwen.com/subject/ejbvfttx.html