zoukankan      html  css  js  c++  java
  • iOS 2D绘图详解(Quartz 2D)之路径(点,直线,虚线,曲线,圆弧,椭圆,矩形)

    前言:一个路径可以包含由一个或者多个shape以及子路径subpath,quartz提供了很多方便的shape可以直接调用。例如:point,line,Arc(圆弧),Curves(曲线),Ellipse(椭圆),矩形(Rectangle).

    对这些path可以进行stroke(描边),也可以进行fill(填充).也可以利用path对一个区域进行截取(clip).

    例如,使用截取圆形区域


    如果对Quartz的基本概念仍然不清楚的,强烈建议看下我之前的这篇文章,不然不能理解

    iOS 2D绘图详解(Quartz 2D)之概述


    Points/Lines

    Quartz中,使用方法CGContextMoveToPoint移动画笔到一个点来开始新的子路径,使用CGContextAddLineToPoint来从当前开始点添加一条线到结束点,注意,CGContextAddLineToPoint调用后,开始点会重新设置,这知道结束点

    举个例子

    代码

    - (void)drawRect:(CGRect)rect {
        CGContextRef context = UIGraphicsGetCurrentContext(); //获得当前context
        //设置颜色
        CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
        CGContextSetStrokeColorWithColor(context, [UIColor lightGrayColor].CGColor);
        //为了颜色更好区分,对矩形描边
        CGContextFillRect(context, rect);
        CGContextStrokeRect(context, rect);
        //实际line和point的代码
        CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);// 设置描边颜色
        CGContextSetLineWidth(context, 4.0);//线的宽度
        CGContextSetLineCap(context, kCGLineCapRound);//线的顶端
        CGContextSetLineJoin(context, kCGLineJoinRound);//线相交的模式
    
        CGContextMoveToPoint(context,10,10);
        CGContextAddLineToPoint(context, 40, 40);
        CGContextAddLineToPoint(context, 10, 80);
        CGContextStrokePath(context);
    }

    这里提一下线的顶端模式,使用CGContextSetLineCap来设置,一共有三种

    线的相交模式,使用CGContextSetLineJoin 来设置,一共也有三种

    虚线
    效果

    代码

        CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
        CGContextSetLineWidth(context, 1.0);
        CGContextSetLineCap(context, kCGLineCapRound);
        CGContextSetLineJoin(context, kCGLineJoinRound);
        CGFloat lengths[] = {2};
        CGContextSetLineDash(context, 1, lengths, 1);
        CGContextMoveToPoint(context,10,10);
        CGContextAddLineToPoint(context, 40, 40);
        CGContextAddLineToPoint(context, 10, 80);
        CGContextStrokePath(context);

    使用到方法CGContextSetLineDash参数详解

    void CGContextSetLineDash (
       CGContextRef _Nullable c,
       CGFloat phase,
       const CGFloat * _Nullable lengths,
       size_t count
    );
    • c 绘制的context,这个不用多说
    • phase,第一个虚线段从哪里开始,例如传入3,则从第三个单位开始
    • lengths,一个C数组,表示绘制部分和空白部分的分配。例如传入[2,2],则绘制2个单位,然后空白两个单位,以此重复
    • count lengths的数量

    圆弧

    Quartz提供了两个方法来绘制圆弧

    • CGContextAddArc,普通的圆弧一部分(以某圆心,某半径,某弧度的圆弧)
    • CGContextAddArcToPoint,用来绘制圆角,下文会详细阐述

    CGContextAddArc参数

    void CGContextAddArc (
       CGContextRef _Nullable c,
       CGFloat x,
       CGFloat y,
       CGFloat radius,
       CGFloat startAngle,
       CGFloat endAngle,
       int clockwise
    );
    • c,context不用剁手
    • x,y指定坐标原点
    • radius,指定半径长度
    • startAngle/endAngle,指定某一段弧度
    • clockwise,1表示顺时针,0表示逆时针
      例如
      这个函数很简单,不放图了
      CGContextAddArc(context,50,50, 25,M_PI_2,M_PI,1);
      CGContextStrokePath(context);

    CGContextAddArcToPoint这个方法比较复杂,但是理解了也没那么难
    函数体

    void CGContextAddArcToPoint (
       CGContextRef _Nullable c,
       CGFloat x1,
       CGFloat y1,
       CGFloat x2,
       CGFloat y2,
       CGFloat radius
    );

    参数

    • c context
    • x1,y1和当前点(x0,y0)决定了第一条切线(x0,y0)->(x1,y1)
    • x2,y2和(x1,y1)决定了第二条切线
    • radius,想切的半径。

    也就是说,
    绘制一个半径为radius的圆弧,和上述 两条直线都相切。

    代码

        CGContextMoveToPoint(context, 100, 50);
        CGContextAddArcToPoint(context,100,0,50,0, 50);
        CGContextStrokePath(context);

    效果

    解释为什么

    图中的两条红线就是上文提到的两条线,分别是(x0,y0)->(x1,y1)和(x1,y1)->(x2,y2),那么和这两条线都想切的自然就是图中的蓝色圆弧了


    椭圆/矩形

    比较简单,这里不多赘述

    示例

        CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
        CGContextAddEllipseInRect(context, CGRectMake(10, 10,40, 20));
        CGContextAddRect(context, CGRectMake(10, 10,40, 20));
        CGContextStrokePath(context);

    效果


    曲线

    Quartz 使用计算机图形学中的多项式来绘制曲线,支持二次和三次曲线。
    利用函数CGContextAddCurveToPoint可以绘制三次曲线,
    函数体

    void CGContextAddCurveToPoint (
       CGContextRef _Nullable c,
       CGFloat cp1x,
       CGFloat cp1y,
       CGFloat cp2x,
       CGFloat cp2y,
       CGFloat x,
       CGFloat y
    );

    参数

    • c context
    • cp1x,cp1y 第一个控制点
    • cp2x,cp2y 第二个控制点
    • x,y 结束点
      具体效果如图

    使用方法CGContextAddQuadCurveToPoint 来绘二次曲线,
    函数体,

    void CGContextAddQuadCurveToPoint (
       CGContextRef _Nullable c,
       CGFloat cpx,
       CGFloat cpy,
       CGFloat x,
       CGFloat y
    );

    参数

      • c context
      • cpx,cpy控制点
      • x,y结束点
        效果
  • 相关阅读:
    随机过程之第一次出现的期望
    js模板引擎介绍搜集
    qt的安装和debug
    $parse/$eval和$observe/$watch如何区分
    angular controller as syntax vs scope
    Angularjs Controller 间通信机制
    Ng-template寄宿方式
    angularjs移除不必要的$watch
    angularJs项目实战!02:前端的页面分解与组装
    推荐几个可以与PhoneGap很好搭配的UI框架
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/5948806.html
Copyright © 2011-2022 走看看