重新看回<<iOS指南开发>>这本书,翻到了贝塞尔曲线
发现自己遗落了这个点,所以尝试使用这个进行画画~,若要说具体的用途的话,可能就是可以自己画个爱心悄悄在女朋友手机上装这个软件吧(滑稽)。
我们可以根据贝塞尔的曲线的画的路径,让一只虫子在上面爬动,也可以是统计图,折线图,扇形各类图形。
贝塞尔曲线是法国数学家耳塞尔在工作中发现的,任何一条曲线都可以通过与它相切的控制线两端的
点的位置来定义。因此,贝塞尔曲线可以用4个点描述,其中两个点描述两个端点,另外两个点描述
每一端的切线。贝塞尔可以分为:二次方贝塞尔曲线与高阶贝塞尔曲线
借用了这位大神的图pandaApe
比起看理论知识,我个人觉得还不如直接上代码,让跟我一样刚涉及到这个的知识的读者敲一遍熟悉的快。
这里我们将用樱桃小丸子为例利用贝塞尔曲线画一张樱桃小丸子的头部视图
//首先我们先把人物对称放在中间
// 确定头部所在的圆心
CGFloat arcCenterX = [UIScreen mainScreen].bounds.size.width / 2;
CGFloat arcCenterY = 180;
// 头部
/***
*CAShapeLayer属于QuartzCore框架,继承自CALayer。CAShapeLayer是在坐标系内绘制贝塞
尔曲线的,通过绘制贝塞尔曲线,设置shape(形状)的path(路径),从而绘制各种各样的图形以及
不规则图形。因此,使用CAShapeLayer需要与UIBezierPath一起使用。
UIBezierPath类允许你在自定义的 View 中绘制和渲染由直线和曲线组成的路径。你可以在初始
化的时候直接为你的UIBezierPath指定一个几何图形。
通俗点就是UIBezierPath用来指定绘制图形路径,而CAShapeLayer就是根据路径来绘图的。
*/
CAShapeLayer* headLayer = [CAShapeLayer layer];
/***
*使用UIBezierPath类可以创建基于矢量的路径,这个类在UIKit中。此类是Core Graphics框
*架关于path的一个封装。使用此类可以定义简单的形状,如椭圆或者矩形,或者有多个直线和曲线
*段组成的形状。
*Bezier Path 基础
*UIBezierPath对象是CGPathRef数据类型的封装。path如果是基于矢量形状的,都用直线和曲
*线段去创建。我们使用直线段去创建矩形和多边形,使用曲线段去创建弧(arc),圆或者其他复
*杂的曲线形状。每一段都包括一个或者多个点,绘图命令定义如何去诠释这些点。每一个直线段或
*者曲线段的结束的地方是下一个的开始的地方。每一个连接的直线或者曲线段的集合成为subpath。
*一个UIBezierPath对象定义一个完整的路径包括一个或者多个subpaths
*/
UIBezierPath *headPath = [UIBezierPath bezierPath];
//头部贝塞尔曲线的画法是由起点、终点、控制点三个参数来画的
//之后不再用这个仔细命名方式;
CGPoint headstartPoint = CGPointMake(arcCenterX - 90, arcCenterY +15);
CGPoint headendPoint = CGPointMake(arcCenterX + 90, arcCenterY+15);
CGPoint headcontrolPoint = CGPointMake(arcCenterX, arcCenterY);
//确立起始点位置
[headPath moveToPoint:headstartPoint];
//利用三点确立一条曲线(二次方贝塞尔曲线)
//其中下面第一个参数填入结束点位置,第二个参数为控制点,即控制曲线的弯曲程度及方向
[headPath addQuadCurveToPoint:headendPoint controlPoint:headcontrolPoint];
//四点控制曲线(三次方贝塞尔曲线)
[headPath addCurveToPoint:headstartPoint
controlPoint1:CGPointMake(arcCenterX + 100, arcCenterY - 150)
controlPoint2:CGPointMake(arcCenterX - 100, arcCenterY - 150)];
//用于下面的方法需要使用多次所以我们将他们成方法;
headLayer.path = headPath.CGPath;
headLayer.fillColor = [UIColor clearColor].CGColor;
headLayer.strokeColor = [UIColor lightGrayColor].CGColor;
[self.view.layer addSublayer:headLayer];
//[self setLayer:headLayer andWithPath:headPath];
这样我们就可以得到一个头的图形
接下来我们把方法封装好,以便下次的使用。
- (void)setLayer:(CAShapeLayer*)layer andWithPath:(UIBezierPath*)path{
layer.path = path.CGPath;
layer.fillColor = [UIColor clearColor].CGColor;
layer.strokeColor = [UIColor lightGrayColor].CGColor;
[self.view.layer addSublayer:layer];
}
接着画脸型。
//脸部
CAShapeLayer* faceLayer = [CAShapeLayer layer];
UIBezierPath* facePath = [UIBezierPath bezierPath];
[facePath moveToPoint:CGPointMake(arcCenterX - 60, arcCenterY - 40)];
[facePath addLineToPoint:CGPointMake(arcCenterX - 56, arcCenterY + 9)];
[facePath addCurveToPoint:CGPointMake(arcCenterX + 56, arcCenterY + 9) controlPoint1:CGPointMake(arcCenterX - 25, arcCenterY + 50) controlPoint2:CGPointMake(arcCenterX + 25, arcCenterY + 50)];
[facePath addLineToPoint:CGPointMake(arcCenterX + 60, arcCenterY - 40)];
// 每个发梢边10,
[facePath addQuadCurveToPoint:CGPointMake(arcCenterX + 50, arcCenterY - 45) controlPoint:CGPointMake(arcCenterX + 55, arcCenterY - 40)];
[facePath addQuadCurveToPoint:CGPointMake(arcCenterX + 52, arcCenterY - 32) controlPoint:CGPointMake(arcCenterX + 48, arcCenterY - 40)];
[facePath addQuadCurveToPoint:CGPointMake(arcCenterX + 35, arcCenterY - 53) controlPoint:CGPointMake(arcCenterX + 35, arcCenterY - 35)];
[facePath addQuadCurveToPoint:CGPointMake(arcCenterX + 25, arcCenterY - 40) controlPoint:CGPointMake(arcCenterX + 28, arcCenterY - 55)];
[facePath addQuadCurveToPoint:CGPointMake(arcCenterX + 15, arcCenterY - 58) controlPoint:CGPointMake(arcCenterX + 20, arcCenterY - 35)];
[facePath addQuadCurveToPoint:CGPointMake(arcCenterX + 5, arcCenterY - 44) controlPoint:CGPointMake(arcCenterX+5 , arcCenterY - 48)];
//中间发梢
[facePath addQuadCurveToPoint:CGPointMake(arcCenterX - 3, arcCenterY - 60) controlPoint:CGPointMake(arcCenterX-5 , arcCenterY - 48)];
[facePath addQuadCurveToPoint:CGPointMake(arcCenterX - 14, arcCenterY - 40) controlPoint:CGPointMake(arcCenterX-14 , arcCenterY - 48)];
[facePath addQuadCurveToPoint:CGPointMake(arcCenterX - 20, arcCenterY - 53) controlPoint:CGPointMake(arcCenterX-23 , arcCenterY - 45)];
[facePath addQuadCurveToPoint:CGPointMake(arcCenterX - 28, arcCenterY - 34) controlPoint:CGPointMake(arcCenterX-26 , arcCenterY - 42)];
[facePath addQuadCurveToPoint:CGPointMake(arcCenterX - 38, arcCenterY - 47) controlPoint:CGPointMake(arcCenterX-35 , arcCenterY - 44)];
[facePath addQuadCurveToPoint:CGPointMake(arcCenterX - 46, arcCenterY - 35) controlPoint:CGPointMake(arcCenterX-42 , arcCenterY - 30)];
[facePath addQuadCurveToPoint:CGPointMake(arcCenterX - 50, arcCenterY - 49) controlPoint:CGPointMake(arcCenterX-48 , arcCenterY - 42)];
[facePath addQuadCurveToPoint:CGPointMake(arcCenterX - 60, arcCenterY - 40) controlPoint:CGPointMake(arcCenterX-55 , arcCenterY - 38)];
[self setLayer:faceLayer andWithPath:facePath];
然后左右耳,个人建议画完左右耳后把这块代码放在脸部之前,这样就不会出现“耳朵”这个挡脸这个现象了。
// 左耳
CAShapeLayer* leftEarLayer = [CAShapeLayer layer];
UIBezierPath* leftEarPath = [UIBezierPath bezierPath];
[leftEarPath moveToPoint:CGPointMake(arcCenterX - 58, arcCenterY - 30)];
[leftEarPath addLineToPoint:CGPointMake(arcCenterX - 57, arcCenterY - 0)];
[leftEarPath addQuadCurveToPoint:CGPointMake(arcCenterX - 58, arcCenterY - 30) controlPoint:CGPointMake(arcCenterX - 75, arcCenterY - 19)];
leftEarPath.lineWidth = 1.5;
[self setLayer:leftEarLayer andWithPath:leftEarPath];
// 右耳
CAShapeLayer* rightEarLayer = [CAShapeLayer layer];
UIBezierPath* rightEarPath = [UIBezierPath bezierPath];
[rightEarPath moveToPoint:CGPointMake(arcCenterX + 58, arcCenterY - 30)];
[rightEarPath addLineToPoint:CGPointMake(arcCenterX + 57, arcCenterY - 0)];
[rightEarPath addQuadCurveToPoint:CGPointMake(arcCenterX + 58, arcCenterY - 30) controlPoint:CGPointMake(arcCenterX + 75, arcCenterY - 19)];
rightEarPath.lineWidth = 1.5;
[self setLayer:rightEarLayer andWithPath:rightEarPath];
剩下脸部各个具体部位
// 左眉毛
CAShapeLayer* leftEyebrowLayer = [CAShapeLayer layer];
UIBezierPath* leftEyebrowPath = [UIBezierPath bezierPath];
[leftEyebrowPath moveToPoint:CGPointMake(arcCenterX - 40, arcCenterY - 35)];
[leftEyebrowPath addQuadCurveToPoint:CGPointMake(arcCenterX - 10, arcCenterY - 35) controlPoint:CGPointMake(arcCenterX - 25, arcCenterY - 50)];
leftEyebrowPath.lineWidth = 2;
[self setLayer:leftEyebrowLayer andWithPath:leftEyebrowPath];
// 右眉毛
CAShapeLayer* rightEyebrowLayer = [CAShapeLayer layer];
UIBezierPath* rightEyebrowPath = [UIBezierPath bezierPath];
[rightEyebrowPath moveToPoint:CGPointMake(arcCenterX + 40, arcCenterY - 35)];
[rightEyebrowPath addQuadCurveToPoint:CGPointMake(arcCenterX + 10, arcCenterY - 35) controlPoint:CGPointMake(arcCenterX + 25, arcCenterY - 50)];
rightEyebrowPath.lineWidth = 2;
[self setLayer:rightEyebrowLayer andWithPath:rightEyebrowPath];
// 左眼
CAShapeLayer* leftEyeLayer = [CAShapeLayer layer];
UIBezierPath* leftEyePath = [UIBezierPath bezierPath];
[leftEyePath moveToPoint:CGPointMake(arcCenterX - 35, arcCenterY - 20)];
[leftEyePath addQuadCurveToPoint:CGPointMake(arcCenterX - 15, arcCenterY - 20) controlPoint:CGPointMake(arcCenterX - 25, arcCenterY - 30)];
leftEyePath.lineWidth = 2.5;
[self setLayer:leftEyeLayer andWithPath:leftEyePath];
// 右眼
CAShapeLayer* rightEyeLayer = [CAShapeLayer layer];
UIBezierPath* rightEyePath = [UIBezierPath bezierPath];
[rightEyePath moveToPoint:CGPointMake(arcCenterX + 35, arcCenterY - 20)];
[rightEyePath addQuadCurveToPoint:CGPointMake(arcCenterX + 15, arcCenterY - 20) controlPoint:CGPointMake(arcCenterX + 25, arcCenterY - 30)];
rightEyePath.lineWidth = 2.5;
[self setLayer:rightEyeLayer andWithPath:rightEyePath];
// 左红晕
CAShapeLayer* leftBallLayer = [CAShapeLayer layer];
UIBezierPath* leftBallPath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(arcCenterX - 42, arcCenterY, 14, 14) cornerRadius:7];
[self setLayer:leftBallLayer andWithPath:leftBallPath];
// 右红晕
CAShapeLayer* rightBallLayer = [CAShapeLayer layer];
UIBezierPath* rightBallPath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(arcCenterX + 28, arcCenterY, 14, 14) cornerRadius:7];
[self setLayer:rightBallLayer andWithPath:rightBallPath];
// 嘴巴
CAShapeLayer* mouthLayer = [CAShapeLayer layer];
UIBezierPath* mouthPath = [UIBezierPath bezierPath];
[mouthPath moveToPoint:CGPointMake(arcCenterX - 13, arcCenterY + 10)];
[mouthPath addLineToPoint:CGPointMake(arcCenterX + 13, arcCenterY + 10)];
[mouthPath addCurveToPoint:CGPointMake(arcCenterX - 13, arcCenterY + 10) controlPoint1:CGPointMake(arcCenterX + 13, arcCenterY + 25) controlPoint2:CGPointMake(arcCenterX - 13, arcCenterY + 25)];
[self setLayer:mouthLayer andWithPath:mouthPath];
这里我们可以得到差不多这样的图形
个人感觉上色了更丑。。。天杀的。
//头部36,32,33
headLayer.fillColor = [UIColor colorWithRed:36/255 green:32/255 blue:33/255 alpha:1].CGColor;
headLayer.strokeColor = [UIColor colorWithRed:36/255 green:32/255 blue:33/255 alpha:1].CGColor;
// 脸部255,229,202
faceLayer.fillColor = [UIColor colorWithRed:255/255.0 green:229/255.0 blue:202/255.0 alpha:1].CGColor;
faceLayer.strokeColor = [UIColor colorWithRed:36/255 green:32/255 blue:33/255 alpha:1].CGColor;
//左耳朵
leftEarLayer.fillColor = [UIColor colorWithRed:255/255.0 green:229/255.0 blue:202/255.0 alpha:1].CGColor;
leftEarLayer.strokeColor = [UIColor colorWithRed:36/255 green:32/255 blue:33/255 alpha:1].CGColor;
//右耳朵
rightEarLayer.fillColor = [UIColor colorWithRed:255/255.0 green:229/255.0 blue:202/255.0 alpha:1].CGColor;
rightEarLayer.strokeColor = [UIColor colorWithRed:36/255 green:32/255 blue:33/255 alpha:1].CGColor;
//左眼
leftEyeLayer.strokeColor = [UIColor colorWithRed:36/255.0 green:32/255.0 blue:33/255.0 alpha:1].CGColor;
//右眼
rightEyeLayer.strokeColor = [UIColor colorWithRed:36/255.0 green:32/255.0 blue:33/255.0 alpha:1].CGColor;
//左眉毛
leftEyebrowLayer.strokeColor = [UIColor colorWithRed:36/255.0 green:32/255.0 blue:33/255.0 alpha:1].CGColor;
//右眉毛
rightEyebrowLayer.strokeColor = [UIColor colorWithRed:36/255.0 green:32/255.0 blue:33/255.0 alpha:1].CGColor;
//左红晕 251,194,170
leftBallLayer.fillColor = [UIColor colorWithRed:251/255.0 green:194/255.0 blue:170/255.0 alpha:1].CGColor;
leftBallLayer.strokeColor = [UIColor clearColor].CGColor;
//右红晕
rightBallLayer.fillColor = [UIColor colorWithRed:251/255.0 green:194/255.0 blue:170/255.0 alpha:1].CGColor;
rightBallLayer.strokeColor = [UIColor clearColor].CGColor;
//嘴巴 240,26,41
mouthLayer.fillColor = [UIColor colorWithRed:240/255.0 green:26/255.0 blue:41/255.0 alpha:1].CGColor;
mouthLayer.strokeColor = [UIColor colorWithRed:36/255 green:32/255 blue:33/255 alpha:1].CGColor;
上色后效果图如下。
Github代码:https://github.com/SenforQ/yingtaoxiaowanzi
读者自己在本地新建工程将里面的ViewController.m替换即可,如果觉得还行麻烦给我一个喜欢或者start吧~