仿射变换简介

仿射变换源于CoreGraphics框架,主要作用是绘制2D级别的图层,几乎所有iOS设备屏幕上的界面元素都是由CoreGraphics来负责绘制。而我们要了解的2D仿射变换是其下负责二维坐标到二维坐标的线性变换工作,它保持了二维图形的“平直性”(即:直线经过变换之后依然是直线,圆弧经过变换之后依然是圆弧)和“平行性”(即:二维图形之间的相对位置关系保持不变,平行线依然是平行线,且直线上点的位置顺序不变),只有依照向量产生的二维线条间的夹角会可能发生变化。仿射变换包括:平移(Translation)、缩放(Scale)、翻转(Flip)、旋转(Rotation)和错切(Shear)。iOS中通常只用到平移、旋转和缩放,同时iOS中CGAffineTransform是一个结构体级别的数据类型,并没有封装成类作为仿射变换,我们通常是在一个view的transform属性中进行访问和设置。常见于手势触发的旋转、平移、缩放,或者动画的类似播放效果。

CGAffineTransform简介
CGAffineTransform结构体代表了一种用于仿射变换矩阵。结构体的参数指定了从一个坐标系的点转化成另外一个坐标系的规则。仿射变换是一种特殊类型的映射,保留在一个路径中的平行线,但不一定保留长度或角度。缩放,旋转,平移是最常用的操作支持的仿射变换,但也可能扭曲。我们通常不会直接创建一个仿射变换,我们只需要根据现有的参数,修改现有的仿射变换。

我们创建一个view,当给它的transform属性赋值的时候,就是我们设置仿射变换的值,我们具体来分析一下仿射变换的具体细节。

    UIView *view = [[UIView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];    view.backgroundColor = [UIColor cyanColor];    //视图的仿射变换设定:旋转    view.transform = CGAffineTransformMakeRotation(M_1_PI);    [self.view addSubview:view];

仿射变换机制

仿射变换是通过下面的矩阵来完成的,一共有9个参数,我们通过这9个参数来进行仿射变换。但是矩阵的最后一列总是0,0,1三个固定的值,所以实际上创建一个变换的结构体只需要6个参数,也就是下面给出的a,b,c,d,tx,ty六个CGFloat类型的参数。

仿射变换是通过下面的矩阵来完成的,一共有9个参数,我们通过这9个参数来进行仿射变换。但是矩阵的最后一列总是0,0,1三个固定的值,所以实际上创建一个变换的结构体只需要6个参数,也就是下面给出的a,b,c,d,tx,ty六个CGFloat类型的参数(通过结构体来描述的六个值)。

CGAffineTransform t = CGAffineTransformMake(CGFloat a, CGFloat b, CGFloat c, CGFloat d, CGFloat tx, CGFloat ty);

变化原理:源视图上的点p(x,y)变化成目标视图中p'(x',y')。对应关系为:

这样源视图上的每一点都这样变换成目标视图的点的过程,就叫做仿射变换。

平移变换:
那么依照上面的矩阵,我们如果想要达到平移的目的,只需要x' = x + tx,y' = y + ty(改变对应点的横纵坐标的位置即可)。那么这样算来,仿射变换的参数中,a = 1,b = 0, c = 0, d = 1。也就是说,我们确定了四个参数,那么我们可以根据自己的需求给定tx,ty,这样就完成了平移的设置,也就是说,平移的仿射变换参数只有tx,ty是不确定的,所以系统的平移只提供了两个参数的原因(内部帮我们补充了固定的参数)。

CGAffineTransformMakeTranslation(CGFloat tx, CGFloat ty)

当然细心的朋友发现还有另外一个平移变换的构造:

CGAffineTransformTranslate(CGAffineTransform t, CGFloat tx, CGFloat ty)

两者的区别当我们对一个视图进行平移操作的时候,前者每次都会从初始位置开始平移(操作前回到原来的位置),后者是从给定参数(通常是上一次的状态)的基础上继续平移。

缩放变换:
缩放的操作,本质上是拉长或缩短了原来的点与点之间的距离,那么也就是说我们只需要让x' = a * x,y' = d *y(将一个点的横坐标和纵坐标放大或者缩小若干倍)。根据平移的经验,那么这样算来,仿射变换的参数中,b = 0, c = 0,tx = 0,ty = 0。也就是说,我们确定了四个参数,那么我们可以根据自己的需求给定a,b,这样就完成了缩放的设置,系统称变换的系数为sx,sy。同样它有两种给定参数的方式:

CGAffineTransformMakeScale(CGFloat sx, CGFloat sy)CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy)

前者依然是在视图初始状态的基础上进行缩放(每次缩放前都先回到初始状态),后者是在前一次操作后的基础上进行缩放操作。

旋转变换:
在iOS中,视图的旋转是按照顺时针进行一个角度(假定为α)的改变,按照数学理解,我们要想让一个点通过旋转到另一个点(不熟悉的朋友复习一下向量的知识),那我们的变化过程应该是这样x' = x * cos α - y *sin α,y’ = x *sin α + y *cos α。所以旋转操作中,tx、ty等于0,a = cosα,b = sinα, c = sinα,d = cosα。虽然有四个参数,但是全部依赖于我们给定的角度,所以系统帮我们封装了起来(角度参数为angle),我们只需要设定一个角度就可以了。所以系统通过的构造旋转操作的参数是:

CGAffineTransformMakeRotation(CGFloat angle)CGAffineTransformRotate(CGAffineTransform t, CGFloat angle)

同样,前者是在初始化的基础上操作旋转(每次旋转先回到初始状态),而后者是在上一个参数(通常情况下是上一次的操作结果)的基础上旋转。

iOS中的2D仿射变换常用的就是以上三种,通常配合手势或者动画来操作。通常iOS中视图的transform支持的就是这三种变换,我们只需要按照自己的需要进行创建就可以,依照系统给定的参数,我们填入合适的值之后,系统会转化成2D仿射对应矩阵,当然如果不满意系统提供的仿射变换,可以自己定义仿射的实现。

iOS下的2D仿射变换机制(CGAffineTransform相关)的更多相关文章

  1. 移动端踩坑之旅-ios下fixed、软键盘相关问题总结

    最近一个项目掉进了移动端的大坑,包括ios下fixed布局,h5唤起键盘等问题,作为一个B端程序员,弱项就是浏览器的兼容性和移动端的适配(毕竟我们可以要求使用chrome),还好这次让我学习了一下相关 ...

  2. iOS下bound,center和frame

    本文转发至:http://www.xuebuyuan.com/1846606.html 在写程序的时候发现,iOS下的坐标.位置很容易弄乱,特别是在不同的坐标系统中,必须完成弄明白一些概念才能做相应的 ...

  3. iOS开发——OC篇&消息传递机制(KVO/NOtification/Block/代理/Target-Action)

     iOS开发中消息传递机制(KVO/NOtification/Block/代理/Target-Action)   今晚看到了一篇好的文章,所以就搬过来了,方便自己以后学习 虽然这一期的主题是关于Fou ...

  4. iOS下WebRTC音视频通话(一)

    在iOS下做IM功能时,难免都会涉及到音频通话和视频通话.QQ中的QQ电话和视频通话效果就非常好,但是如果你没有非常深厚的技术,也没有那么大的团队,很难做到QQ那么快速和稳定的通话效果. 但是利用We ...

  5. iOS Runtime的消息转发机制

    前面我们已经讲解Runtime的基本概念和基本使用,如果大家对Runtime机制不是很了解,可以先看一下以前的博客,会对理解这篇博客有所帮助!!! Runtime基本概念:https://www.cn ...

  6. 【移动端debug-4】iOS下setTimeout无法触发focus事件的解决方案

    开篇总结:其实目前无法解决这个bug. 这两天做项目遇到了这个case,项目需求是打开页面的时候,input元素自动弹起键盘.由于各种方面的考虑,我们希望通过setTimeout延时200毫秒让inp ...

  7. iOS中消息的传递机制

    本文中,会经常提及接收者[recipient]和发送者[sender].在消息传递机制中具体是什么意思,我们可以通过一个示例来解释:一个table view是发送者,而它的delegate就是接收者. ...

  8. 苹果系统iOS、macOS应用管理机制

    iOS.macOS系统应用管理机制 苹果系统包括:iOS.macOS.watchOS.tvOS.应用软件的生命周期为:开发.上线.安装.使用.卸载.这篇文档将从应用生命周期的各个环节介绍苹果系统对应用 ...

  9. iOS下使用SHA1WithRSA算法加签源码

    首先了解一下几个相关概念,以方便后面遇到的问题的解决: RSA算法:1977年由Ron Rivest.Adi Shamirh和LenAdleman发明的,RSA就是取自他们三个人的名字.算法基于一个数 ...

随机推荐

  1. 洛谷P2759 奇怪的函数

    P2759 奇怪的函数 题目描述 使得 x^x 达到或超过 n 位数字的最小正整数 x 是多少? 输入输出格式 输入格式: 一个正整数 n 输出格式: 使得 x^x 达到 n 位数字的最小正整数 x ...

  2. 坑爹的 Java 可变参数,把我整得够惨。。

    最近在写一个功能点,用了 Java 中的可变参数,真是把我搞得够惨.. 什么是可变参数? 就是方法参数用 Object... args 三个点形式,一个参数可以接收多个参数. 实际的代码就不帖了,来看 ...

  3. mac for Idea配置Tomcat

    参考链接地址:http://blog.csdn.net/zsy3313422/article/details/52583091 IntelliJ使用 ##使用IntelliJ IDEA配置web项目时 ...

  4. EasyPOI 教程以及完整工具类的使用

    因为项目的原因需要用到POI来操作Excel 文档,以前都是直接使用POI来操作的,但是最近听到easypoi的存在,所以自己简单的尝试了下! 别说,他还真的挺好用的 Easypoi介绍 Easypo ...

  5. [題解](水)luogu_P1372又是畢業季1

    被入門難度的題虐...... 作者: kkksc03 吉祥物 更新时间: 2013-07-14 19:00 在Ta的博客查看    78   By lzn 数论水题一道. 首先,若可能的最大公约数为a ...

  6. Jmeter跨线程组传参

      我们知道,同一线程组中可以通过“正则表达式提取器”获取其中一个取样器的响应结果中的参数,直接传给线程组中的其他取样器.但其他线程组中的取样器也想使用同样的参数时,无法直接获取.举个例子: 提取“登 ...

  7. JXl常用解析详解

    目的: java解析 excel 无非就是apache poi 或者 jxl 两者在使用上其实都差不多,关键还是看你自己熟悉那个,用那个!我也是初次接触jxl 看很多博客说 jxl只适用于处理小数据量 ...

  8. Codeforces 183C(有向图上的环长度)

    因为公用一个系统所以大家求gcd:衡量各点之间的拓扑位置,如果到达同一点有不同的长度则取gcd. #include <cstdio> #include <cstring> #i ...

  9. jQuery基础(1)

    一.jQuery的介绍 1.为什么要使用jQuery? 在用js写代码时,会遇到一些问题,如下: 1)window.onload 事件有事件覆盖的问题,因此只能写一个事件: 2)代码容错性差: 3)浏 ...

  10. PHPstudy安装redis扩展

    PHPstudy安装redis扩展 第一步:查看PHP版本(phpinfo) 第二步:下载所需的扩展(http://pecl.php.net/package/redis   .   http://wi ...