iOS Principle:CGAffineTransform

??‍? Github Demo

方便记忆:

  • 本质:处理形变的类,通过"仿射变换矩阵"对控件的平移、缩放、旋转
  • 方法:
    • CGAffineTransformMakeTranslation:以初始位置为基准,在x轴方向上平移x单位,在y轴方向上平移y单位
    • CGAffineTransformMakeScale:以初始位置为基准,在x轴方向上缩放x倍,在y轴方向上缩放y倍
    • CGAffineTransformMakeRotation:以初始位置为基准,将坐标系统逆时针旋转angle弧度(弧度=π/180×角度,M_PI弧度代表180角度)
    • CGAffineTransformTranslate:以一个已经存在的形变为基准,在x轴方向上平移x单位,在y轴方向上平移y单位
    • CGAffineTransformScale:以一个已经存在的形变为基准,在x轴方向上缩放x倍,在y轴方向上缩放y倍
    • CGAffineTransformRotate:以一个已经存在的形变为基准,将坐标系统逆时针旋转angle弧度(弧度=π/180×角度,M_PI弧度代表180角度)
    • CGAffineTransformIdentity:transform属性默认值为CGAffineTransformIdentity,可以在形变之后设置该值以还原到最初状态

概述

A structure for holding an affine transformation matrix.

CGAffineTransform 是一个用于处理形变的类,其可以改变控件的平移、缩放、旋转等,其坐标系统采用的是二维坐标系,即向右为x轴正方向,向下为y轴正方向。

这个矩阵和坐标之间的关系如下:

struct CGAffineTransform { CGFloat a; CGFloat b; CGFloat c; CGFloat d; CGFloat tx; CGFloat ty; }; 
typedef struct CGAffineTransform CGAffineTransform;
复制代码

我们通过 UIImageView 的 transform 方法演示这一特性,注意默认情况下 UIImageView 的 User Interaction 为不可交互状态,需要设置一下:


方法介绍

  • CGAffineTransformMakeTranslation

CGAffineTransformMakeTranslation 实现以初始位置为基准,在x轴方向上平移x单位,在y轴方向上平移y单位。

CGAffineTransform transform = CGAffineTransformMakeTranslation(-100, 150);
imageView.transform = transform;
复制代码
  • CGAffineTransformMakeScale

CGAffineTransformMakeScale 实现以初始位置为基准,在x轴方向上缩放x倍,在y轴方向上缩放y倍

CGAffineTransform transform = CGAffineTransformMakeScale(2, 2);
imageView.transform = transform;
复制代码
  • CGAffineTransformMakeRotation

CGAffineTransformMakeRotation 实现以初始位置为基准,将坐标系统逆时针旋转angle弧度(弧度=π/180×角度,M_PI弧度代表180角度)

CGAffineTransform transform = CGAffineTransformMakeRotation(M_PI);
imageView.transform = transform;
复制代码
  • CGAffineTransformTranslate

CGAffineTransformTranslate 实现以一个已经存在的形变为基准,在x轴方向上平移x单位,在y轴方向上平移y单位

CGAffineTransform transform = CGAffineTransformMakeTranslation(50, 50);
imageView.transform = CGAffineTransformTranslate(transform, 50, 50);
复制代码
  • CGAffineTransformScale

CGAffineTransformScale 实现以一个已经存在的形变为基准,在x轴方向上缩放x倍,在y轴方向上缩放y倍

CGAffineTransform transform = CGAffineTransformMakeScale(2, 0.5);
imageView.transform = CGAffineTransformScale(transform, 2, 1);
复制代码
  • CGAffineTransformRotate

CGAffineTransformRotate 实现以一个已经存在的形变为基准,将坐标系统逆时针旋转angle弧度(弧度=π/180×角度,M_PI弧度代表180角度)

CGAffineTransform transform = CGAffineTransformMakeRotation(M_PI*0.25);
imageView.transform = CGAffineTransformRotate(transform, M_PI*0.25);
复制代码
  • CGAffineTransformIdentity

transform属性默认值为CGAffineTransformIdentity,可以在形变之后设置该值以还原到最初状态

imageView.transform = CGAffineTransformIdentity;
复制代码

CGAffineTransform原理

CGAffineTransform形变是通过"仿射变换矩阵"来控制的

  • 平移是矩阵相加
  • 旋转与缩放则是矩阵相乘

为了合并矩阵运算中的加法和乘法,引入了齐次坐标的概念。

齐次坐标提供了用矩阵运算把二维、三维甚至高维空间中的一个点集从一个坐标系变换到另一个坐标系的有效方法.

CGAffineTransform形变就是把二维形变使用一个三维矩阵来表示,其中第三列总是(0,0,1),形变通过前两列来控制,系统提供了CGAffineTransformMake结构体来控制形变。

CGAffineTransformMake(CGFloat a, CGFloat b, CGFloat c, CGFloat d, CGFloat tx, CGFloat ty)
复制代码

三维变换矩阵如下

变换矩阵左乘向量,将空间中的一个点集从一个坐标系变换到另一个坐标系中,计算方式如下

计算结果

由上可知:

  • tx用来控制在x轴方向上的平移
  • ty用来控制在y轴方向上的平移
  • a用来控制在x轴方向上的缩放
  • d用来控制在y轴方向上的缩放
  • abcd共同控制旋转

对应的代码实现:

1)平移CGAffineTransformMakeTranslation原理

self.demoImageView.transform = CGAffineTransformMakeTranslation(100, 100);
self.demoImageView.transform = CGAffineTransformMake(1, 0, 0, 1, 100, 100);
复制代码

2)缩放CGAffineTransformMakeScale原理

self.demoImageView.transform = CGAffineTransformMakeScale(2, 0.5);
self.demoImageView.transform = CGAffineTransformMake(2, 0, 0, 0.5, 0, 0);
复制代码

3)旋转CGAffineTransformMakeRotation原理

self.demoImageView.transform = CGAffineTransformMakeRotation(M_PI*0.5);
self.demoImageView.transform = CGAffineTransformMake(cos(M_PI * 0.5), sin(M_PI * 0.5), -sin(M_PI * 0.5), cos(M_PI * 0.5), 0, 0);
复制代码

4)初始状态CGAffineTransformIdentity原理

self.demoImageView.transform = CGAffineTransformIdentity;
self.demoImageView.transform = CGAffineTransformMake(1, 0, 0, 1, 0, 0);
复制代码

以上文章整理自:https://www.jianshu.com/p/ca7f9bc62429

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值