The UIBezierPath class lets you define a path consisting of straight and curved line segments and render that path in your custom views. You use this class initially to specify just the geometry for your path. Paths can define simple shapes such as rectangles, ovals, and arcs or they can define complex polygons that incorporate a mixture of straight and curved line segments. After defining the shape, you can use additional methods of this class to render the path in the current drawing context.UIBezierPath类允许您定义一个路径组成的直线和曲线段和渲染路径在您的自定义视图。你使用这个类最初指定的几何路径。路径可以定义简单的形状如矩形、椭圆、弧或他们可以定义复杂的多边形,将直线和曲线段的混合物。定义形状之后,您可以使用这个类的其他方法来呈现在当前绘图上下文路径
- 使用贝赛尔曲线创建简单图形
- (void)drawRect:(CGRect)rect{
//创建UIBezierPath
UIBezierPath *path = [UIBezierPath bezierPath];
//绘制三角形
[path moveToPoint:CGPointMake(100, 10)];
[path addLineToPoint:CGPointMake(130, 40)];
[path addLineToPoint:CGPointMake(70, 40)];
[[UIColor redColor] setFill];
[path fill];//填充模式
[path closePath];
//绘制剪切区域
[path moveToPoint:CGPointMake(100, 80)];
[path addLineToPoint:CGPointMake(105, 100)];
[path addLineToPoint:CGPointMake(95, 100)];
[path closePath];
[path appendPath:[UIBezierPath bezierPathWithRect:rect]];
path.usesEvenOddFillRule = NO;
[path addClip];
//绘制轴
[path removeAllPoints];//画另一条线,不与之前的线连接
[path moveToPoint:CGPointMake(100, 40)];
[path addLineToPoint:CGPointMake(100, 100)];
//设置周宽度
[path setLineWidth:5];
[path stroke];
}
- 绘制箭头
- (void) drawRect:(CGRect)rect{
//1.获取图形上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
//2. 绘制大三角
CGContextMoveToPoint(ctx, 100, 0);
CGContextAddLineToPoint(ctx, 140, 40);
CGContextAddLineToPoint(ctx, 60, 40);
CGContextSetRGBFillColor(ctx, 1, 0, 0, 1.0);
CGContextFillPath(ctx);
//关闭路径
CGPDFContextClose(cox);
#pragma >>>>下方的剪切部分
//3 小三角
CGContextMoveToPoint(ctx, 100, 80);
CGContextAddLineToPoint(ctx, 110, 100);
CGContextAddLineToPoint(ctx, 90, 100);
CGContextClosePath(ctx);
//添加剪切区域
CGContextAddRect(ctx, rect);
//用奇偶规则剪切
CGContextEOClip(ctx);
//4 绘制轴
CGContextMoveToPoint(ctx, 100, 40);
CGContextAddLineToPoint(ctx, 100, 100);
CGContextSetLineWidth(ctx, 20);
CGContextStrokePath(ctx);
}
- 渐变色
- (void) drawRect:(CGRect)rect{
//1.获取图形上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
//2. 绘制大三角
CGContextMoveToPoint(ctx, 100, 0);
CGContextAddLineToPoint(ctx, 140, 40);
CGContextAddLineToPoint(ctx, 60, 40);
CGContextSetRGBFillColor(ctx, 1, 0, 0, 1.0);
CGContextFillPath(ctx);
//关闭路径
CGPDFContextClose(ctx);
#pragma >>>>下方的剪切部分
//3 小三角
CGContextMoveToPoint(ctx, 100, 80);
CGContextAddLineToPoint(ctx, 110, 100);
CGContextAddLineToPoint(ctx, 90, 100);
CGContextClosePath(ctx);
//添加剪切区域
CGContextAddRect(ctx, rect);
//用奇偶规则剪切
CGContextEOClip(ctx);
//4 绘制轴
CGContextMoveToPoint(ctx, 100, 40);
CGContextAddLineToPoint(ctx, 100, 100);
CGContextSetLineWidth(ctx, 20);
// CGContextStrokePath(ctx);//关闭,下方渐变才生效
//确定渐变区域
//stroke ->fill
CGContextReplacePathWithStrokedPath(ctx);
//保存设置状态
CGContextSaveGState(ctx);
CGContextClip(ctx);
//绘制渐变颜色
CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
const CGFloat components[] = {
0.2,0.6,0.8,0.6,//开始的颜色
0.5,0.9,0.3,0.8,//中间的颜色1
0.7,0.5,0.2,0.7,//中间的颜色2
0.4,0.7,0.7,0.4,//结束的颜色
};
//设置渐变区域
const CGFloat locations[] = {0,0.32,0.56,1};
/**
space 颜色空间对象
components 颜色的数组,存储的事rgb颜色
location 颜色所在位置
count :颜色的个数 = locations的个数
*/
CGGradientRef gradientref = CGGradientCreateWithColorComponents(space, components, locations, 4);
//绘制渐变
//颜色0对应的开始点,颜色数组中的结束点位置
CGContextDrawLinearGradient(ctx, gradientref,CGPointMake(90, 100),CGPointMake(110, 100),kCGGradientDrawsBeforeStartLocation);
//释放颜色空间,渐变的对象
CGColorSpaceRelease(space);
CGGradientRelease(gradientref);
//恢复以前的区域
CGContextRestoreGState(ctx);
![渐变色](http://upload-images.jianshu.io/upload_images/2382884-3f853c36bdc2f7c1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- 矩阵变幻 CGContextTranslateCTM
//1.获取图形上下文 Translate平移 Rotate旋转 cale缩放
CGContextRef ctx=UIGraphicsGetCurrentContext();
//5.矩阵变换,
//a.坐标轴的变换
CGRect bounds=self.bounds;
//平移坐标轴
CGContextTranslateCTM(ctx, 0, bounds.size.height);
//翻转Y的坐标轴
CGContextScaleCTM(ctx, 1, -1);
//移动位置,沿着x轴移动100
CGContextTranslateCTM(ctx, 100, 0);
//旋转
CGContextRotateCTM(ctx, radians(90));
//缩放
CGContextScaleCTM(ctx, 0.5, 0.5);
![翻转,平移](http://upload-images.jianshu.io/upload_images/2382884-e1e55a6e96391a85.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
# 非零绕数
在图形学中判断一个点是否在多边形内,若多边形不是自相交的,那么可以简单的判断这个点在多边形内部还是外部;若多边形是自相交的,那么就需要根据非零环绕数规则和奇-偶规则判断。
在图形学中判断一个点是否在多边形内,若多边形不是自相交的,那么可以简单的判的,那么就需要根据非零环绕数规则和奇-偶规则判断。判断多边形是否是自相交的:多边形在平面内除顶点外还有其他公共点内-外测试
不自交的多边形:多边形仅在顶点处连接,而在平面内没有其他公共点,此时可以自相交的多边形:多边形在平面内除顶点外还有其他公共点,此时划分内-外部分(1)奇-偶规则(Odd-even Rule):奇数表示在多边形内,偶数表示在多边形外从任意位置p作一条射线,若与该射线相交的多边形边的数目为奇数,则p是多边(2)非零环绕数规则(Nonzero Winding Number Rule):若环绕数为0表示在多首先使多边形的边变为矢量。将环绕数初始化为零。再从任意位置p作一条射线。
边计数,每当多边形的边从右到左穿过射线时,环绕数加1,从左到右时,环绕数减1则p为内部点,否则,p是外部点。
参考[1]中例子如下,判断点p是否在多边形内,从点p向外做一条射线(可以任意方向),多边形的边从线时环数加1,最后环数不为0,即表示在多边形内部。
当然,非零绕数规则和奇偶规则会判断出现矛盾的情况,如下图所示,左侧表示用 奇充。右侧图用非零绕环规则判断出绕数为2,非0表示在多边形内部,所以填充。
断
![屏幕快照 2016-09-16 下午2.24.03.png](http://upload-images.jianshu.io/upload_images/2382884-232fd9f074fe5937.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
需形
当
左
断这个点在多边形内部还是外部;若多边形是自相交
直接划分内-外部分。要采用以下的方法。
内部点,否则是外部点。边形内,非零表示在多边形外
从p点沿射线方向移动时,对在每个方向上穿过射线的。处理完多边形的所有相关边之后,若环绕数为非零,
到右经过射线时环数减1,多边形的边从右往左经过射
偶规则判断绕环数为2 ,表示在多边形外,所以没有填
以需
形多
当1
![屏幕快照 2016-09-16 下午2.24.13.png](http://upload-images.jianshu.io/upload_images/2382884-12e07f1b60e19011.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
左
奇
另外一个例子,如下
非零环绕数规则和奇-偶规则(Non-Zero Winding Number Rule&&Odd-even Ru1.CGContextClip 使用非零环绕数规则来判断当前路径和裁剪路径的交集。2.CGContextEOClip 使用奇偶环绕数规则来判断当前路径和裁剪路径的交集。
![
](http://upload-images.jianshu.io/upload_images/2382884-15c331d9d7fe106d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
u