仿射变换源于CoreGraphics框架,主要作用是绘制2D级别的图层,2D仿射变换是其下负责二维坐标到二维坐标的线性变换工作,它保持了二维图形的“平直性”(即:直线经过变换之后依然是直线,圆弧经过变换之后依然是圆弧)和“平行性”(即:二维图形之间的相对位置关系保持不变,平行线依然是平行线,且直线上点的位置顺序不变)只有依照向量产生的二维线条间的夹角会可能发生变化。
仿射变换包括:平移(Translation)、缩放(Scale)、翻转(Flip)、旋转(Rotation)和错切(Shear)。CGAffineTransform是一个结构体级别的数据类型,并没有封装成类作为仿射变换,我们通常是在一个view的transform属性中进行访问和设置。常见于手势触发的旋转、平移、缩放,或者动画的类似播放效果。
CGAffineTransform结构体代表了一种用于仿射变换矩阵。结构体的参数指定了从一个坐标系的点转化成另外一个坐标系的规则。
仿射变换是通过下面的矩阵来完成的,一共有9个参数,我们通过这9个参数来进行仿射变换。但是矩阵的最后一列总是0,0,1三个固定的值,所以实际上创建一个变换的结构体只需要6个参数,也就是下面给出的a,b,c,d,tx,ty六个CGFloat类型的参数。
变化原理:源视图上的点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)
//缩放仿射
x' = a * x,
y' = d *y
那么也就是说我们只需要让x' = a * x,y' = d *y(将一个点的横坐标和纵坐标放大或者缩小若干倍)。根据平移的经验,那么这样算来,仿射变换的参数中,b = 0, c = 0,tx = 0,ty = 0。也就是说,我们确定了四个参数,那么我们可以根据自己的需求给定a,d,这样就完成了缩放的设置,系统称变换的系数为sx,sy。同样它有两种给定参数的方式:
CGAffineTransformMakeScale(CGFloat sx, CGFloat) sy)CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy)
//旋转仿射
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)
//缩放仿射
x' = a * x,
y' = d *y
那么也就是说我们只需要让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)