贝塞尔曲线
贝塞尔曲线,又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线。一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋,我们在绘图工具上看到的钢笔工具就是来做这种矢量曲线的
下面分别是 一阶、二阶、三阶、高阶 曲线图
贝塞尔曲线的应用
贝塞尔曲线在iOS中有一个对应的类,叫做UIBezierPath,UIBezierPath是Core Graphics框架关于路径的封装
UIBezierPath通常与CAShapeLayer配合使用。CAShapeLayer继承自CALayer,它拥有CALayer的所有属性。UIBezierPath为CAShapeLayer提供路径, CAShapeLayer在提供的路径中进行渲染, 绘制出图形
属性介绍
-
CGPath:将UIBezierPath类转换成CGPath,类似于UIColor的CGColor
-
empty:只读类型,路径上是否有有效的元素
-
bounds:和view的bounds是不一样的,它获取path的X坐标、Y坐标、宽度,但是高度为0
-
currentPoint:当前path的位置,可以理解为path的终点
-
lineWidth:path宽度
-
lineCapStyle:path端点样式,有3种样式
-
lineJoinStyle:拐角样式
-
miterLimit:最大斜接长度(只有在使用kCGLineJoinMiter是才有效), 边角的角度越小,斜接长度就会越大
为了避免斜接长度过长,使用lineLimit属性限制,如果斜接长度超过miterLimit,边角就会以KCALineJoinBevel类型来显示
-
flatness:弯曲路径的渲染精度,默认为0.6,越小精度越高,相应的更加消耗性能。
-
usesEvenOddFillRule:单双数圈规则是否用于绘制路径,默认是NO。 - UIRectCorner:角
-
创建在rect内的矩形:
- (instancetype)bezierPathWithRect:(CGRect)rect:
-
创建在rect里的内切曲线:
- (instancetype)bezierPathWithOvalInRect:(CGRect)rect:
-
创建带有圆角的矩形,当矩形变成正圆的时候,Radius就不再起作用: + (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius
-
设定特定的角为圆角的矩形:
- (instancetype)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii
-
创建圆弧
- (instancetype)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise
-
通过已有路径创建路径:
UIBezierPath *path_A = [UIBezierPath bezierPath];
[path_A moveToPoint:CGPointMake(200, 50)];
[path_A addLineToPoint:CGPointMake(250, 100)];
path_A.lineWidth = 5.0f;
UIBezierPath *path_B = [UIBezierPath bezierPathWithCGPath:path_A.CGPath];
[path_B stroke];
- 创建二次贝塞尔曲线
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(200, 300)];
[path addQuadCurveToPoint:endPoint controlPoint:controlPoint];
[path stroke];
- 创建三次贝塞尔曲线
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(200, 200)];
[path addCurveToPoint:endPoint controlPoint1:controlPoint1 controlPoint2:controlPoint2];
[path stroke];
- 添加圆弧
/**
* 添加圆弧
* @param center 圆点
* @param radius 半径
* @param startAngle 起始位置
* @param endAngle 结束为止
* @param clockwise 是否顺时针方向
*/
- (void)createAddArcWithCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise{
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(200, 400)];
[path addLineToPoint:CGPointMake(225, 410)];
[path addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:clockwise];
[path closePath];
[path removeAllPoints];
[path stroke];
}
- 追加路径
/**
* 追加路径
*/
- (void)appendPath{
UIBezierPath *path_A = [UIBezierPath bezierPath];
[path_A moveToPoint:CGPointMake(200, 500)];
[path_A addLineToPoint:CGPointMake(225, 410)];
UIBezierPath *path_B = [UIBezierPath bezierPath];
[path_B moveToPoint:CGPointMake(200, 600)];
[path_B addLineToPoint:CGPointMake(225, 500)];
[path_A appendPath:path_B];
[path_A stroke];
}
- 创建翻转路径,即起点变成终点,终点变成起点
- (void)createReversingPath{
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(50, 50)];
[path addLineToPoint:CGPointMake(100, 50)];
path.lineWidth = 5.0f;
NSLog(@"%@",NSStringFromCGPoint(path.currentPoint));
UIBezierPath *path_b = [path bezierPathByReversingPath];
NSLog(@"%@",NSStringFromCGPoint(path_b.currentPoint));
[path_b stroke];
}
- 路径进行仿射变换
- (void)createApplyTransform{
CGAffineTransform transform = CGAffineTransformMakeScale(2, 2);
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(10, 50)];
[path addLineToPoint:CGPointMake(100, 50)];
[path applyTransform:transform];
path.lineWidth = 5.0f;
[path stroke];
}
- 创建虚线
/**
* 创建虚线
* @param pattern C类型线性数据
* @param count pattern中数据个数
* @param phase 起始位置
*/
- (void)createLineDash:(nullable const CGFloat *)pattern count:(NSInteger)count phase:(CGFloat)phase{
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(50, 50)];
[path addLineToPoint:CGPointMake(100, 50)];
[path setLineDash:pattern count:count phase:0.0];
[path stroke];
}
- 设置颜色
- (void)setLineColor:(UIColor *)lineColor fillColor:(UIColor *)fillColor{
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 100, 100, 100)];
[lineColor setStroke];
[fillColor setFill];
[path stroke];
[path fill];
}
- 设置描边混合模式
- (void)setFillWithBlendMode{
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 100, 100, 100)];
[[UIColor redColor] setFill];
[path fillWithBlendMode:kCGBlendModeSaturation alpha:0.6];
[path fill];
}
- (void)setStrokeWithBlendMode{
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 100, 100, 100)];
[[UIColor greenColor] setStroke];
path.lineWidth = 10.0f;
[path strokeWithBlendMode:kCGBlendModeSaturation alpha:1.0];
[path stroke];
}
- 修改当前图形上下文的绘图区域可见,随后的绘图操作导致呈现内容只有发生在指定路径的填充区域
- (void)createAddClip{
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 100, 100, 100)];
[[UIColor greenColor] setStroke];
[path addClip];
[path stroke];
}