如何在iOS中使用bezierpath创build月牙形月亮?

如何使用bezierpath绘制一个闭合的新月,当笔画和填充是可configuration的? 所以汽车我可以得到一次曲线,但还没有find一个策略来连接和绘制另一条曲线。

在这里输入图像说明

如果你想要更好的接近天文上正确的新月形(外弧是180度),我可能会build议如下:

 CGFloat angle = M_PI_2 * 0.60; // how much of a crescent do you want (must be less than M_PI_2 and greater than zero) UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:-M_PI_2 endAngle:M_PI_2 clockwise:TRUE]; [path addArcWithCenter:CGPointMake(center.x - radius * tan(angle), center.y) radius:radius / cosf(angle) startAngle:M_PI_2 - angle endAngle:angle - M_PI_2 clockwise:FALSE]; [path closePath]; 

这产生:

结果

如您所见,path基本上由两个圆弧定义,一个顺时针,一个逆时针。 内弧的中心,半径和起始angular度和结束angular度的细节是基本三angular学的问题(但是实际的公式将根据精确的期望的外观和感觉而变化)。 例如,在我的代码片段中,我上面的代码中的angular度是下图中的蓝色angular度,然后计算将用于确定正确的起始angular度和结束angular度以及内弧中心的红色三angular形。

如何


下面,有人问这个逆时针旋转90度如下:

在这里输入图像说明

在Swift中,那将是:

 let path = UIBezierPath(arcCenter: center, radius: radius, startAngle: -.pi, endAngle: 0, clockwise: true) path.addArc(withCenter: CGPoint(x: center.x, y: center.y + radius * tan(angle)), radius: radius / cos(angle), startAngle: -angle, endAngle: -.pi + angle, clockwise: false) path.close() 

贝塞尔path可以由两个弧构成。 在迅速:

 var big = UIBezierPath() var angle: CGFloat = 5.0 // in radians var rad : CGFloat = 50.0 big.addArcWithCenter(CGPointMake(0.0, 0.0), radius: rad, startAngle:-angle/2.0, endAngle: angle/2.0, clockwise: true) big.addArcWithCenter(CGPointMake(rad * cos(angle/2.0), 0.0), radius: rad * sin(angle/2.0), startAngle: 3.14/2.0, endAngle: -3.14/2.0, clockwise: false) big.closePath() 

将创build一个绘制时的path如下所示:

在这里输入图像说明

编辑:Objective-C与填充和描边左上angular在x,y = 100,100):

 UIBezierPath *big = [UIBezierPath new]; CGFloat angle = 5.0; // in radians CGFloat rad = 50.0; CGFloat x= 100.0; CGFloat y = 100.0; [big addArcWithCenter:CGPointMake(x, y) radius:rad startAngle:-angle/2.0 endAngle:angle/2.0 clockwise:YES]; [big addArcWithCenter:CGPointMake(x + rad * cos(angle/2.0), y) radius: rad * sin(angle/2.0) startAngle:M_PI_2 endAngle:-M_PI_2 clockwise:NO]; big.lineWidth = 2.0; [[UIColor lightGrayColor] setFill]; [[UIColor darkGrayColor] setStroke]; [big closePath]; [big fill]; [big stroke]; 

对于复杂的形状绘制,我可以build议你一个伟大的应用程序称为PaintCode 。 有了它,您可以导入vectorgraphics,并获取格式化为bezierPath的相关path。 有一个试用版。 这是我将你提供的形状转换成SVG文件后得到的:

 UIBezierPath* bezierPath = UIBezierPath.bezierPath; [bezierPath moveToPoint: CGPointMake(47.18, 5.32)]; [bezierPath addCurveToPoint: CGPointMake(67.96, 17.62) controlPoint1: CGPointMake(55.58, 7.5) controlPoint2: CGPointMake(61.06, 10.72)]; [bezierPath addCurveToPoint: CGPointMake(81.46, 49.5) controlPoint1: CGPointMake(77.56, 27.15) controlPoint2: CGPointMake(81.46, 36.45)]; [bezierPath addCurveToPoint: CGPointMake(67.96, 81.37) controlPoint1: CGPointMake(81.46, 62.55) controlPoint2: CGPointMake(77.56, 71.85)]; [bezierPath addCurveToPoint: CGPointMake(47.18, 93.67) controlPoint1: CGPointMake(61.06, 88.27) controlPoint2: CGPointMake(55.58, 91.5)]; [bezierPath addCurveToPoint: CGPointMake(24.98, 93.67) controlPoint1: CGPointMake(41.33, 95.17) controlPoint2: CGPointMake(30.83, 95.17)]; [bezierPath addCurveToPoint: CGPointMake(9.16, 86.32) controlPoint1: CGPointMake(19.81, 92.32) controlPoint2: CGPointMake(12.38, 88.87)]; [bezierPath addLineToPoint: CGPointMake(7.06, 84.52)]; [bezierPath addLineToPoint: CGPointMake(10.13, 80.47)]; [bezierPath addCurveToPoint: CGPointMake(19.13, 61.27) controlPoint1: CGPointMake(13.81, 75.52) controlPoint2: CGPointMake(18.01, 66.67)]; [bezierPath addCurveToPoint: CGPointMake(18.83, 38.25) controlPoint1: CGPointMake(20.33, 55.5) controlPoint2: CGPointMake(20.18, 43.42)]; [bezierPath addCurveToPoint: CGPointMake(9.98, 19.95) controlPoint1: CGPointMake(17.11, 31.57) controlPoint2: CGPointMake(14.03, 25.35)]; [bezierPath addLineToPoint: CGPointMake(6.31, 15.07)]; [bezierPath addLineToPoint: CGPointMake(8.78, 13.05)]; [bezierPath addCurveToPoint: CGPointMake(24.08, 5.55) controlPoint1: CGPointMake(12.16, 10.27) controlPoint2: CGPointMake(18.53, 7.12)]; [bezierPath addCurveToPoint: CGPointMake(47.18, 5.32) controlPoint1: CGPointMake(29.93, 3.82) controlPoint2: CGPointMake(41.11, 3.75)]; [bezierPath closePath]; self.shapeLayer = [CAShapeLayer new]; self.shapeLayer.path = bezierPath.CGPath; self.shapeLayer.frame = CGRectMake(80, 80, 85, 98); self.shapeLayer.strokeColor = [UIColor blueColor].CGColor; self.shapeLayer.lineWidth = 4; self.shapeLayer.fillColor = [UIColor lightGrayColor].CGColor; [self.layer addSublayer:self.shapeLayer]; 

结果:

产生的图像