美文网首页iOS 绘图iosiOS
IOS图形绘制路径 CGPATH & CGCONTEX

IOS图形绘制路径 CGPATH & CGCONTEX

作者: LiYaoPeng | 来源:发表于2017-02-05 12:45 被阅读511次

    独立CGPath总结

    CGPathCreateMutable //创建一个可变图形的路径 需要自己释放
    CGPathCreateWithEllipseInRect //创建一个椭圆形的不可改变的路径
    CGPathCreateWithRect //创建一个不变的矩形路径
    CGPathCreateCopy //创建一个不可变的可以拷贝的路径
    CGPathCreateCopyByDashingPath //创建一个虚线路径可以复制的
    CGPathCreateCopyByStrokingPath //创建一个画的路径
    CGPathCreateMutableCopy //创建一个现有的图形路径的副本
     //由一个转换矩阵变换一个图形路径创建一个不可变的副本
    CGPathCreateCopyByTransformingPath
    //创建一个由一个转换矩阵变换一个图形路径的可变副本
    CGPathCreateMutableCopyByTransformingPath
    
    
    CGPathRelease //递减保留的图形路径计数
    CGPathRetain //增加保留的图形路径计数
    
    CGPathAddArc 一个//弧形追加一个可变图形的路径, 可能由直线段之前
    CGPathAddEllipseInRect //添加一个适合的椭圆在矩形的内部
    CGPathEqualToPath //两个图形路径是否相等
    CGPathGetBoundingBox //返回图形路径中包含所有点的包围盒
    CGPathGetPathBoundingBox //返回图形路径的边界框
    CGPathGetCurrentPoint //返回当前点的路径
    CGPathGetTypeID //返回Quartz图形路径的核心基础类型的标识符
    
    CGPathIsEmpty //指示路径是否为空
    CGPathIsRect //图形路径指示是否代表一个矩形
    CGPathContainsPoint //检查一个点是否在图形路径中
    

    与CGContext关联的Path总结

    点&线

    注意

    1. AddLineToPoint实现方式在线条alpha为1,即不透明的时候和AddLines一样,而且是实时画线。
    2. 但是当线条半透明的时候,AddLines在一条线自身重叠时不会透明度重叠。
    3. 而AddLineToPoint却会导致透明度重叠,且move touch的点出也会出现透明度重叠,会显示成点和点之间透明度正确,点上不透明的问题。
    //获取上下文
    CGContextRef context = UIGraphicsGetCurrentContext();
        //点(在Context中移动画笔到(0,0)个点)
    CGContextMoveToPoint(context, 0, 0);
        
        //线(画笔从上一个点画到(1,1)这个点)
    CGContextAddLineToPoint(context, 1, 1);
       
        //添加点的坐标
        CGPoint points[] = {
            CGPointMake(0, 0),
            CGPointMake(2, 2),
            CGPointMake(3, 3)
        };
    int count = sizeof(points)/sizeof(points[0]);//求出poins长度
    CGContextAddLines(context, points, count);//画线
        /*注意
        AddLineToPoint实现方式在线条alpha为1,即不透明的时候和AddLines一样,而且是实时画线。
         但是当线条半透明的时候,AddLines在一条线自身重叠时不会透明度重叠。
         而AddLineToPoint却会导致透明度重叠,且move touch的点出也会出现透明度重叠,会显示成点和点之间透明度正确,点上不透明的问题。
         */
    

    曲线

    一种
    void CGContextAddArc (
      CGContextRef c,    
      CGFloat x,             //圆心的x坐标
      CGFloat y,  //圆心的x坐标
      CGFloat radius,  //圆的半径
      CGFloat startAngle,    //开始弧度
      CGFloat endAngle,  //结束弧度
      int clockwise          //0表示顺时针,1表示逆时针
    );
    假如想创建一个完整的圆圈,那么 开始弧度就是0 结束弧度是 2pi, 因为圆周长是 2*pi*r.
    最后,函数执行完后,current point就被重置为(x,y).
    还有一点要注意的是,假如当前path已经存在一个subpath,那么这个函数执行的另外一个效果是
    会有一条直线,从current point到弧的起点
     
    第二种
    void CGContextAddArcToPoint (
      CGContextRef c,
      CGFloat x1, //端点1的x坐标
      CGFloat y1, //端点1的y坐标
      CGFloat x2, //端点2的x坐标
      CGFloat y2, //端点2的y坐标
      CGFloat radius //半径
    );
    原理:首先画两条线,这两条线分别是 current point to (x1,y1) 和(x1,y1) to (x2,y2).
    这样就是出现一个以(x1,y1)为顶点的两条射线,
    然后定义半径长度,这个半径是垂直于两条射线的,这样就能决定一个圆了,更好的理解看下图,不过个人认为下图所标的 tangent point 1的位置是错误的。
    最后,函数执行完后,current point就被重置为(x2,y2).
    还有一点要注意的是,假如当前path已经存在一个subpath,那么这个函数执行的另外一个效果是
    会有一条直线,从current point到(x1,y1)
    Paths - happy dog - 又一个部落格
    

    传说中的不规则的曲线

    画曲线,一般是一条直线,然后定义几个控制点,使直线变弯曲。
    三次曲线函数
    void CGContextAddCurveToPoint (
      CGContextRef c,
      CGFloat cp1x, //控制点1 x坐标
      CGFloat cp1y, //控制点1 y坐标
      CGFloat cp2x, //控制点2 x坐标
      CGFloat cp2y, //控制点2 y坐标
      CGFloat x, //直线的终点 x坐标
      CGFloat y //直线的终点 y坐标
    );
    假如第二个控制点(cp2x,cp2y)比(cp1x,cp1y) 更接近current point,那么会形成一个封闭的曲线
    Paths - happy dog - 又一个部落格
     
    二次曲线函数
    void CGContextAddQuadCurveToPoint (
      CGContextRef c,
      CGFloat cpx, //控制点 x坐标
      CGFloat cpy, //控制点 y坐标
      CGFloat x, //直线的终点 x坐标
      CGFloat y //直线的终点 y坐标
    );
    

    裁剪的方法:

    CGConextClip;
    CGContextEOClip;
    CGContextClipToRect;
    CGContextClipToRects;
    CGContextClipToMask;
    

    图像绘制

    UIGraphicsBeginImageContextWithOptions
    UIGraphicsEndImageContext
    

    PDF绘制

    UIGraphicsBeginPDFContextToFile(ToData)
    UIGraphicsEndPDFContext
    

    翻转屏幕变换:

    CGContextTranslateCTM(graphicsContext, 0.0, drawingRect.size.height);
    CGContextScaleCTM(graphicsContext, 1.0, -1.0);
    

    ** CGPATH &CGCONTEXT相关联的CGPath中的对应关系**

    CGPathCreateMutable = CGContextBeginPath//创建一个路径
    CGPathMoveToPoint = CGContextMoveToPoint//画笔(路径)从哪里开始
    CGPathAddLineToPoint = CGContextAddLineToPoint//添加一个点(线)
    CGPathAddCurveToPoint = CGContextAddCurveToPoint//创建一个曲线
    CGPathAddEllipseInRect = CGContextAddEllipseInRect//创建一个椭圆
    CGPathAddArc = CGContextAddArc//创建一个圆形路径
    CGPathAddRect = CGContextAddRect//创建一个矩形路径
    CGPathCloseSubPath = CGContextCloseSubPath//闭合路径
    

    UIBezierPath

    好了看完了上面的各种函数是不是头都大了那么看看我们的UIBezierPath

    属性

    CGPath:将UIBezierPath类转换成CGPath,类似于UIColor的CGColor
    
    empty:只读类型,路径上是否有有效的元素
    
    bounds:和view的bounds是不一样的,它获取path的X坐标、Y坐标、宽度,但是高度为0
    
    currentPoint:当前path的位置,可以理解为path的终点
    
    lineWidth:path宽度
    
    lineCapStyle:path端点样式,有3种样式
          kCGLineCapButt:无端点
          kCGLineCapRound:圆形端点
          kCGLineCapSquare:方形端点(样式上和kCGLineCapButt是一样的,但是比kCGLineCapButt长一点)
    
    lineJoinStyle:拐角样式
          kCGLineJoinMiter:尖角
          kCGLineJoinRound:圆角
          kCGLineJoinBevel:缺角
    
    miterLimit:最大斜接长度(只有在使用kCGLineJoinMiter是才有效), 边角的角度越小,斜接长度就会越大
    为了避免斜接长度过长,使用lineLimit属性限制,如果斜接长度超过miterLimit,边角就会以KCALineJoinBevel类型来显示
    
    flatness:弯曲路径的渲染精度,默认为0.6,越小精度越高,相应的更加消耗性能。
    
    usesEvenOddFillRule:单双数圈规则是否用于绘制路径,默认是NO
    
    UIRectCorner:角
      UIRectCornerTopLeft:左上角
      UIRectCornerTopRight:右上角
      UIRectCornerBottomLeft:左下角
      UIRectCornerBottomRight:右下角
      UIRectCornerAllCorners:所有四个角
    

    UIBezierPath
    1.创建UIBezierPath

    //矩形路径(rect矩形的位置和大小)
    -(instancetype)bezierPathWithRect:(CGRect)rect:
    
    //创建在rect里的内切曲线: (参数:rect-矩形的Frame)
    +(instancetype)bezierPathWithOvalInRect:(CGRect)rect:
    
    //创建带有圆角的矩形,当矩形变成正圆的时候,Radius就不再起作用:
    //rect:矩形的Frame  cornerRadius:圆角大小)
    + (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius
    
    //圆角的矩形(设定特定的角为)
    /*
    rect:矩形的Frame
    corners:指定的圆角     
    cornerRadii:圆角的大小
    */
    + (instancetype)bezierPathWithRoundedRect:(CGRect)rect
                            byRoundingCorners:(UIRectCorner)corners
                                  cornerRadii:(CGSize)cornerRadii;
    
    //圆弧
    /*
    center->圆点
    radius->半径
    startAngle->起始位置
    endAngle->结束为止
    clockwise->是否顺时针方向
    */
    
    + (instancetype)bezierPathWithArcCenter:(CGPoint)center
                                     radius:(CGFloat)radius
                                 startAngle:(CGFloat)startAngle
                                   endAngle:(CGFloat)endAngle
                                  clockwise:(BOOL)clockwise;
    
    //通过已有路径创建路径:
    //CGPath->已有路径
    + (instancetype)bezierPathWithCGPath:(CGPathRef)CGPath
    

    一些对象方法

    -(void)moveToPoint:(CGPoint)point; //移动到某一点:(point:目标位置)
    -(void)addLineToPoint:(CGPoint)point; //绘制一条线:(point:目标位置)
    - (void)closePath;//闭合路径,即在终点和起点连一根线
    -(void)appendPath:(UIBezierPath *)bezierPath;//追加路径
    -(UIBezierPath *)bezierPathByReversingPath;//扭转路径,即起点变成终点,终点变成起点
    -(void)applyTransform:(CGAffineTransform)transform;//路径进行仿射变换
    -(void)fill; //填充;
    -(void)stroke; //描边,路径创建需要描边才能显示出来;
    -(void)setStroke;//设置描边颜色,需要在设置后调用描边方法:
    -(void)fillWithBlendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha; //设置描边的混合模式
    
    //设置描边的混合模式
    //blendMode->混合模式 alpha->透明度
    -(void)fillWithBlendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha;
    
    //设置填充的混合模式:
    //blendMode:混合模式  alpha:透明度
    -(void)strokeWithBlendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha;
    
    //修改当前图形上下文的绘图区域可见,随后的绘图操作导致呈现内容只有发生在指定路径的填充区域
    -(void)addClip;
    
    
    /**
     *  创建虚线
     *  @param pattern C类型线性数据
     *  @param count   pattern中数据个数
     *  @param phase   起始位置
     */
    - (void)setLineDash:(nullable const CGFloat *)pattern
                  count:(NSInteger)count
                  phase:(CGFloat)phase;
    
    
    
    
    //清空路径:
    -(void)removeAllPoints;
    
    /**
     *  创建三次贝塞尔曲线
     *  @param endPoint      终点
     *  @param controlPoint1 控制点1
     *  @param controlPoint2 控制点2
     */
    -(void)addCurveToPoint:(CGPoint)endPoint
             controlPoint1:(CGPoint)controlPoint1
             controlPoint2:(CGPoint)controlPoint2;
    
    
    /**
     *  创建二次贝塞尔曲线
     *  @param endPoint     终点
     *  @param controlPoint 控制点
     */
    -(void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint;
    
    
    /**
     *  创建圆弧
     *  @param center     圆点
     *  @param radius     半径
     *  @param startAngle 起始位置
     *  @param endAngle   结束为止
     *  @param clockwise  是否顺时针方向
     */
    - (void)addArcWithCenter:(CGPoint)center
                      radius:(CGFloat)radius
                  startAngle:(CGFloat)startAngle
                    endAngle:(CGFloat)endAngle
                   clockwise:(BOOL)clockwise;
    
    

    相关文章

      网友评论

        本文标题:IOS图形绘制路径 CGPATH & CGCONTEX

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