Path-CGContext

Paths中的几个重要元素

重绘调用     setNeedsDisplay

Points
 void CGContextMoveToPoint (
    CGContextRef c,
    CGFloat x,
    CGFloat y
 );
 指定一个点成为current point
 Quartz会跟踪current point一般执行完一个相关函数后,current point都会相应的改变.
 
Lines
 相关的几个函数
 void CGContextAddLineToPoint (
    CGContextRef c,
    CGFloat x,
    CGFloat y
 );
 创建一条直线,从current point到 (x,y)
 然后current point会变成(x,y)
 
 void CGContextAddLines (
    CGContextRef c,
    const CGPoint points[],
    size_t count
 );
 创建多条直线,比如points有两个点,那么会画两条直线 从current point到 (x1,y1),
 然后是(x1,y1)到(x2,y2)
 然后current point会变成points中的最后一个点
 
Arcs
 两种方法创建弧度 第一种
 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 - 又一个部落格
Curves
 画曲线,一般是一条直线,然后定义几个控制点,使直线变弯曲。
 三次曲线函数
 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坐标
 );
 执行完函数貌似current point不会变化,没有具体测试过
 Paths - happy dog - 又一个部落格
 
Ellipses
 void CGContextAddEllipseInRect (
    CGContextRef context,
    CGRect rect  //一矩形
 ); 
 如果矩形是一个正方形,那么画出来就是一个圆
 执行完函数貌似current point不会变化,没有具体测试过
Rectangles
 void CGContextAddRect (
    CGContextRef c,
    CGRect rect
 );
 
 一次性画出多个矩形
 void CGContextAddRects (
    CGContextRef c,
    const CGRect rects[],
    size_t count
 );
 需要注意的是,画矩形有一些特别,current point没有发生变化
 

Creating a Path
 调用函数 CGContextBeginPath 开始创建路径,线调用函数CGContextMoveToPoint设置起点
 然后开始画自己想画的路径,注意一下几点:
 1.Lines, arcs, and curves,是从current point开始的
 2.假如想封闭一条路径,那么调用函数 CGContextClosePath 把当前点和起点连接起来
 3.当在画 arcs的时候,Quartz会画一条线从current point 到 starting point
 4.画矩形的时候不会有第三条那这样的的一条直线
 5.创建完路径后,必须调用 painting 函数  fill or stroke the path,不然不会画上面东东在相应的设备上】
 6.开始创建一个新的路径的时候,使用函数 CGContextBeginPath。
 
 重复利用路径的相关函数和数据类型
 CGPathCreateMutable 类似于 CGContextBeginPath
 CGPathMoveToPoint 类似于 CGContextMoveToPoint
 CGPathAddLineToPoint 类似于 CGContextAddLineToPoint
 CGPathAddCurveToPoint 类似于 CGContextAddCurveToPoint
 CGPathAddEllipseInRect 类似于 CGContextAddEllipseInRect
 CGPathAddArc 类似于 CGContextAddArc
 CGPathAddRect 类似于 CGContextAddRect
 CGPathCloseSubpath 类似于 CGContextClosePath
 CGPathRef
 CGMutablePathRef
 
 用CGContextAddPath函数把一个路径添加到graphics context中
 void CGContextAddPath (
    CGContextRef context,
    CGPathRef path
 );

Painting a Path
 Stroking :画出路径
 Filling :填充路径的封闭区域
 
 影响Stroking的参数
 Line width
  void CGContextSetLineWidth (
     CGContextRef c,
     CGFloat width
  );
 Line join:线转弯的时候的样式,比如圆滑的方式
  void CGContextSetLineJoin (
     CGContextRef c,
     CGLineJoin join
  );
Paths - happy dog - 又一个部落格Paths - happy dog - 又一个部落格Paths - happy dog - 又一个部落格
  
 Line cap:线的两端的样式,比如两端变的圆滑
  void CGContextSetLineCap (
     CGContextRef c,
     CGLineCap cap
  );
Paths - happy dog - 又一个部落格Paths - happy dog - 又一个部落格Paths - happy dog - 又一个部落格
 
 Miter limit:当Line join的模式是Miter join的时候,这个参数会有影响
  void CGContextSetMiterLimit (
     CGContextRef c,
     CGFloat limit
  );
 Line dash pattern:虚线相关
  void CGContextSetLineDash (
     CGContextRef c,
     CGFloat phase,
     const CGFloat lengths[],
     size_t count
  );
Paths - happy dog - 又一个部落格
 
 Stroke color space
  void CGContextSetStrokeColorSpace (
     CGContextRef c,
     CGColorSpaceRef colorspace
  );
 Stroke color
  void CGContextSetStrokeColor (
     CGContextRef c,
     const CGFloat components[]
  );
  void CGContextSetStrokeColorWithColor (
     CGContextRef c,
     CGColorRef color
  );
 Stroke pattern(和透明度相关)
  void CGContextSetStrokePattern (
     CGContextRef c,
     CGPatternRef pattern,
     const CGFloat components[]
  );


 Stroking的相关函数
 Strokes当前path.
 void CGContextStrokePath (
    CGContextRef c
 );
 
 Strokes 指定的 矩形.
 void CGContextStrokeRect (
    CGContextRef c,
    CGRect rect
 );
 
 Strokes 指定的 矩形, 使用指定的宽度.
 void CGContextStrokeRectWithWidth (
    CGContextRef c,
    CGRect rect,
    CGFloat width
 );
  
 Strokes 指定的椭圆.
 void CGContextStrokeEllipseInRect (
    CGContextRef context,
    CGRect rect
 );
 
 Strokes 一些直线.
 void CGContextStrokeLineSegments (
    CGContextRef c,
    const CGPoint points[],
    size_t count
 );
 
 决定是Stroking 还是Filling
 void CGContextDrawPath (
    CGContextRef c,
    CGPathDrawingMode mode
 );
  
Filling a Path
填充一个路径的时候,路径里面的子路径都是独立填充的。
假如是重叠的路径,决定一个点是否被填充,有两种规则
1,nonzero winding number rule:非零绕数规则,假如一个点被从左到右跨过,计数器+1,从右到左跨过,计数器-1,最后,如果结果是0,那么不填充,如果是非零,那么填充。
2,even-odd rule: 奇偶规则,假如一个点被跨过,那么+1,最后是奇数,那么要被填充,偶数则不填充,和方向没有关系。
Paths(待续) - happy dog - 又一个部落格
 
 Function Description 
 CGContextEOFillPath  使用奇偶规则填充当前路径
 CGContextFillPath  使用非零绕数规则填充当前路径
 CGContextFillRect  填充指定的矩形
 CGContextFillRects  填充指定的一些矩形
 CGContextFillEllipseInRect  填充指定矩形中的椭圆
 CGContextDrawPath  两个参数决定填充规则,kCGPathFill表示用非零绕数规则,kCGPathEOFill表示用奇偶规则,kCGPathFillStroke表示填充,kCGPathEOFillStroke表示描线,不是填充

Setting Blend Modes
设置当一个颜色覆盖上另外一个颜色,两个颜色怎么混合
默认方式是
result = (alpha * foreground) + (1 - alpha) * background

CGContextSetBlendMode :设置blend mode.
CGContextSaveGState :保存blend mode.
CGContextRestoreGState:在没有保存之前,用这个函数还原blend mode.

下面两张图,第一张是背景图,第二张是前景图,都是不透明的图片
Paths(待续) - happy dog - 又一个部落格Paths(待续) - happy dog - 又一个部落格
 
 Note:  这个规则也可以应用于图片,用函数:CGContextSetBlendMode 来设置
   
Normal Blend Mode
这个模式,就是默认的模式,前景图覆盖了背景图.
Paths(待续) - happy dog - 又一个部落格
 
Multiply Blend Mode
调用函数CGContextSetBlendMode  的时候,使用参数 kCGBlendModeMultiply.
混合了两种颜色,最终的颜色都会比原先的两种颜色暗。
Paths(待续) - happy dog - 又一个部落格
 
Screen Blend Mode
使用参数:kCGBlendModeScreen
把前景和背景图的颜色先反过来,然后混合,结果混合的地方比先前的颜色都要亮,前景图没有混合到得地方变成白色?
Paths(待续) - happy dog - 又一个部落格
 
Overlay Blend Mode
使用参数kCGBlendModeOverlay
明亮取决于背景图
Paths(待续) - happy dog - 又一个部落格
 
Darken Blend Mode
kCGBlendModeDarken
Paths(待续) - happy dog - 又一个部落格
 
Lighten Blend Mode
kCGBlendModeLighten
Paths(待续) - happy dog - 又一个部落格
 
Color Dodge Blend Mode
kCGBlendModeColorDodge
Paths(待续) - happy dog - 又一个部落格
 
Color Burn Blend Mode
kCGBlendModeColorBurn
Paths(待续) - happy dog - 又一个部落格
 
Soft Light Blend Mode
kCGBlendModeSoftLight
Paths(待续) - happy dog - 又一个部落格
 
 Hard Light Blend Mode
kCGBlendModeHardLight
Paths(待续) - happy dog - 又一个部落格
 
Difference Blend Mode
kCGBlendModeDifference
Paths(待续) - happy dog - 又一个部落格
 
Exclusion Blend Mode
kCGBlendModeExclusion
Paths(待续) - happy dog - 又一个部落格
 
Hue Blend Mode
kCGBlendModeHue
Paths(待续) - happy dog - 又一个部落格
 
Saturation Blend Mode
kCGBlendModeSaturation
Paths(待续) - happy dog - 又一个部落格
 
Color Blend Mode
kCGBlendModeColor
Paths(待续) - happy dog - 又一个部落格
 
Luminosity Blend Mode
kCGBlendModeLuminosity
Paths(待续) - happy dog - 又一个部落格
 
Clipping to a Path
这个用在,假如我们只想把图片的部分打印到屏幕的时候

CGContextBeginPath (context);
CGContextAddArc (context, w/2, h/2, ((w>h) ? h : w)/2, 0, 2*PI, 0);
CGContextClosePath (context);
CGContextClip (context);

file:///Users/user03/Downloads/Paths.webarchive
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容