zoukankan      html  css  js  c++  java
  • iOS 2D绘图详解(Quartz 2D)之Transform(CTM,Translate,Rotate,Scale)

    前言:Quartz默认采用设备无关的user space来进行绘图,当context(画板)建立之后,默认的坐标系原点以及方向也就确认了,可以通过CTM(current transformation matrix)来修坐标系的原点。从数组图像处理的角度来说,就是对当前context state乘以一个状态矩阵。其中的矩阵运算开发者可以不了解。


    以下,会一一个Demo图解,坐标系的位移,旋转,sacle

    最初的状态和代码

    新建一个CustomView,.m文件

    @implementation CustomView
    
    - (void)drawRect:(CGRect)rect {
        CGContextRef context = UIGraphicsGetCurrentContext();
    
        CGContextAddRect(context, CGRectMake(10,10,40, 20));
        CGContextSetFillColorWithColor(context,[UIColor blueColor].CGColor);
        CGContextFillPath(context);
    }
    -(instancetype)initWithFrame:(CGRect)frame{
        if (self = [super initWithFrame:frame]) {
            self.opaque = NO;
            self.layer.borderColor = [UIColor lightGrayColor].CGColor;
            self.layer.borderWidth = 1.0;
        }
        return self;
    }
    @end
    

    调用

      CustomView * customView = [[CustomView alloc] initWithFrame:CGRectMake(100, 100,100, 100)];
        [self.view addSubview:customView];

    图解


    Translate

    假如我们在绘制之前,进行坐标系移动会是什么效果呢?
    代码

    - (void)drawRect:(CGRect)rect {
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextTranslateCTM(context,10, 10);
    
        CGContextAddRect(context, CGRectMake(10,10,40, 20));
        CGContextSetFillColorWithColor(context,[UIColor blueColor].CGColor);
        CGContextFillPath(context);
    }

    效果

    代码中,我们是还是在(10,10)点绘制,但是要注意,当前坐标系的原点已经移了


    Rotate

    在Transform的基础上我们再Rotate,45度,注意CGContextRotateCTM传入的参数是弧度
    代码

    - (void)drawRect:(CGRect)rect {
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextTranslateCTM(context,10, 10);
        CGContextRotateCTM(context,M_PI_4);
        CGContextAddRect(context, CGRectMake(10,10,40, 20));
        CGContextSetFillColorWithColor(context,[UIColor blueColor].CGColor);
        CGContextFillPath(context);
    }

    效果


    Scale

    对于Scale相对来说,好理解一点,无非就是成比例放大缩小。
    这里不花坐标系了
    代码

    - (void)drawRect:(CGRect)rect {
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextTranslateCTM(context,10, 10);
        CGContextRotateCTM(context,M_PI_4);
        CGContextScaleCTM(context,0.5, 0.5);
        CGContextAddRect(context, CGRectMake(10,10,40, 20));
        CGContextSetFillColorWithColor(context,[UIColor blueColor].CGColor);
        CGContextFillPath(context);
    }

    效果


    状态保存,恢复

    在复杂的绘图中,我们可能只是想对一个subpath进行旋转移动,缩放。这时候,状态堆栈就起到作用了。
    代码

    - (void)drawRect:(CGRect)rect {
        CGContextRef context = UIGraphicsGetCurrentContext();
        //保存状态,入栈
        CGContextSaveGState(context);
        CGContextTranslateCTM(context,10, 10);
        CGContextRotateCTM(context,M_PI_4);
        CGContextScaleCTM(context,0.5, 0.5);
        CGContextAddRect(context, CGRectMake(10,10,40, 20));
        CGContextSetFillColorWithColor(context,[UIColor blueColor].CGColor);
        CGContextFillPath(context);
        CGContextRestoreGState(context);// 推出栈顶部状态
    
        //这里坐标系已经回到了最开始的状态
        CGContextAddRect(context, CGRectMake(0, 0, 10, 10));
        CGContextFillPath(context);
    }

    效果


    Affine Transforms

    可以通过以下方法先创建放射矩阵,然后然后再把放射矩阵映射到CTM

      • CGAffineTransform
      • CGAffineTransformTranslate
      • CGAffineTransformMakeRotation
      • CGAffineTransformRotate
      • CGAffineTransformMakeScale
      • CGAffineTransformScale
  • 相关阅读:
    layer 刷新某个页面
    C# Server.MapPath的使用方法
    .net mvc + layui做图片上传(二)—— 使用流上传和下载图片
    ASP.NET MVC4.0 后台获取不大前台传来的file
    安卓手机修改host
    mvc 页面 去掉转义字符
    educoder数据库实训课程-shell语句总结
    python selenium实现自动操作chrome的某网站数据清洗【此篇为jupyter notebook直接导出.md】
    LeetCode_27移除元素【数组】
    LeetCode_26 删除排序数组中的重复项【数组】
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/5948981.html
Copyright © 2011-2022 走看看