美文网首页
仿射变换

仿射变换

作者: 无题007 | 来源:发表于2017-09-05 11:29 被阅读189次

UIViewtransform属性是一个CGAffineTransform类型,用于在二维空间做旋转、缩放和平移。CGAffineTransform是一个可以和二维空间向量做乘法的3x2的矩阵:


CGPoint的每一列和CGAffineTransform矩阵的每一行对应元素相乘再求和,就形成了一个新的CGPoint`类型的结果。要解释一下图中显示的灰色元素,为了能让矩阵做乘法,左边矩阵的列数一定要和右边矩阵的行数个数相同,所以要给矩阵填充一些标志值,使得既可以让矩阵做乘法,有不改变运算结果,并且没必要存储这些添加的值,因为它们的值不会发生变化,但是要用来做运算。
因此,通常会用3x3(而不是2x3)的矩阵做二维变换,你可能会见到3行2列格式的矩阵,这就是所谓的以列为主的格式,上图就是。只要能保持一致,哪种格式无所谓。

当对图层应用变换矩阵,图层矩形内的每一个点都被相应地做变换,从而形成一个新的四边形的形状。CGAffineTransform中的“仿射”的意思是无论变换矩阵用什么值,图层中平行的两条线在变换之后仍然保持平行,CGAffineTransform可以做出任意符合上述标注的变换,下面看一些仿射和非仿射的图:

创建一个CGAffineTransform

下面几个函数都创建了一个CGAffineTransform实例

CGAffineTransformMakeRotation(CGFloat angle)
CGAffineTransformMakeScale(CGFloat sx, CGFloat sy)
CGAffineTransformMakeTranslation(CGFloat tx, CGFloat ty)

旋转和缩放变换都可以很好解释--分别旋转或者缩放一个向量的值。平移变换是指每个点都移动了向量指定的x或者y值 -- 所以如果向量代表了一个点,那它就平移了这个点的距离。

UIView可以通过设置transform属性做变换,但实际上它只是封装了内部图层的变换。
CALayer同样也有一个transform属性,但它的类型是CATransform3D,而不是CGAffineTransformCALayer对应于UIViewtransform属性叫做affineTransform

看一个代码示例 对图层做45度顺时针旋转:

@interface ViewController ()

@property (nonatomic, weak) IBOutlet UIView *layerView;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    //rotate the layer 45 degrees
    CGAffineTransform transform = CGAffineTransformMakeRotation(M_PI_4);
    self.layerView.layer.affineTransform = transform;
}

@end

这里需要注意一下M_PI_4这里是弧度,弧度用pi的倍数表示,一个pi是180度 45度即是四分之一pi。

混合变换

Core Graphics 提供一系列的函数可以在一个变换的基础上做更深层次的变换,如果做一个既要缩放又要旋转的变换,这就会非常有用了:

CGAffineTransformRotate(CGAffineTransform t, CGFloat angle)
CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy)
CGAffineTransformTranslate(CGAffineTransform t, CGFloat tx, CGFloat ty)

当操纵一个变换的时候,初始生成一个什么都不做的变换很重要--也就是创建一个CGAffineTransform类型的空值,矩阵论中称作单位矩阵,Core Graphics 同样也提供了一个方便的常量:

CGAffineTransformIdentity

最后,如果需要混合两个已经存在的变换矩阵,就可以使用如下方法,在两个变换的基础上创建一个新的变换:

CGAffineTransformConcat(CGAffineTransform t1, CGAffineTransform t2);

下面咱们来实现一个简单的混合变换:先缩小50%,再旋转30度,最后向右移动200个像素

- (void)viewDidLoad
{
    [super viewDidLoad];
    //create a new transform
    CGAffineTransform transform = CGAffineTransformIdentity; 
    //scale by 50%
    transform = CGAffineTransformScale(transform, 0.5, 0.5);
    //rotate by 30 degrees
    transform = CGAffineTransformRotate(transform, M_PI / 180.0 * 30.0);
    //translate by 200 points
    transform = CGAffineTransformTranslate(transform, 200, 0);
    //apply transform to layer
    self.layerView.layer.affineTransform = transform;
}

注意:变换顺序会影响最终的结果,旋转之后的平移和平移之后的旋转结果可能不同。

相关文章

  • 第四篇:CALayer能力之仿射变换和3D变换

    目录 一、UIView的仿射变换 1、单仿射变换 2、混合仿射变换 3、CGAffineTransformIden...

  • iOS 仿射变换

    一、iOS 仿射变换CGAffineTransform详解IOS开发UI篇--仿射变换(CGAffineTrans...

  • 仿射变换

    参考资料: 马同学:如何通俗的解释仿射变换 1. 仿射变换的作用: 通过仿射变换对图片进行旋转、平移、缩放等操作以...

  • 图片处理-opencv-7.图像几何变换

    图像几何变换 1.图像仿射变换 图像仿射变换又称为图像仿射映射,是指在几何中,一个向量空间进行一次线性变换并接上一...

  • 高级动画学习心得笔记(五)变换

    5.1 仿射变换 5.1.1 仿射变换基础 UIView的transform属性是一个CGAffineTransf...

  • 详细解析 CGAffineTransform 矩阵

    CGAffineTransform 是对于仿射变换矩阵进行了封装,而要理解仿射变换(affine transfor...

  • opencv python版-lesson 11

    缩放,平移,旋转.仿射变换,透视变换

  • 仿射变换

    UIView的transform属性是一个CGAffineTransform类型,用于在二维空间做旋转、缩放和平移...

  • 仿射变换

    仿射变换(affinement)是由一个线性变换和平移组成的,如图所示 1. SLAM中的仿射变换 在SLAM里,...

  • 仿射变换

    参考 http://www.cnblogs.com/ghj1976/p/5199086.html 变换模型是指根据...

网友评论

      本文标题:仿射变换

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