在Objective-C中绘制起始和结束angular度的椭圆

我正在编写一个iPad应用程序,在该应用程序中,将呈现形状的XML对象呈现在屏幕上的graphics中。 我想渲染的对象之一是弧线。 基本上这些弧为我提供了一个边界矩形以及一个开始和结束angular度。

给定属性:

  • X
  • ÿ
  • 宽度
  • 高度
  • 由startAngle
  • endAngle

有了这些值,我需要绘制弧(其实质上是椭圆的一部分)。 我不能使用以下内容:

UIBezierPath *arc = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(x, y, width, height)]; [UIColor blackColor] setStroke]; [arc stroke]; 

因为它绘制了一个完整的椭圆。 基本上我需要上面的,但它需要考虑到开始和结束的angular度,所以只有一部分的椭圆显示。 我想这将涉及绘制一个三次贝塞尔曲线或二次贝塞尔曲线。 问题是我不知道如何计算我给出的信息的起点,终点或控制点。

你可以通过在椭圆的graphics周围设置一个剪辑path来达到你想要的效果。

 CGContextSaveGState(theCGContext); CGPoint center = CGPointMake(x + width / 2.0, y + height / 2.0); UIBezierPath* clip = [UIBezierPath bezierPathWithArcCenter:center radius:max(width, height) startAngle:startAngle endAngle:endAngle clockwise:YES]; [clip addLineToPoint:center]; [clip closePath]; [clip addClip]; UIBezierPath *arc = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(x, y, width, height)]; [[UIColor blackColor] setStroke]; [arc stroke]; CGContextRestoreGState(theCGContext); 

剪切的确切半径并不重要。 它需要足够大,所以它只能夹住椭圆的末端,而不是通过所需的弧线。

这个类别将有所帮助。

 #import <Foundation/Foundation.h> @interface UIBezierPath (OvalSegment) + (UIBezierPath *)bezierPathWithOvalInRect:(CGRect)rect startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle; + (UIBezierPath *)bezierPathWithOvalInRect:(CGRect)rect startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle angleStep:(CGFloat)angleStep; @end #import "UIBezierPath+OvalSegment.h" @implementation UIBezierPath (OvalSegment) + (UIBezierPath *)bezierPathWithOvalInRect:(CGRect)rect startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle angleStep:(CGFloat)angleStep { CGPoint center = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect)); CGFloat xRadius = CGRectGetWidth(rect)/2.0f; CGFloat yRadius = CGRectGetHeight(rect)/2.0f; UIBezierPath *ellipseSegment = [UIBezierPath new]; CGPoint firstEllipsePoint = [self ellipsePointForAngle:startAngle withCenter:center xRadius:xRadius yRadius:yRadius]; [ellipseSegment moveToPoint:firstEllipsePoint]; for (CGFloat angle = startAngle + angleStep; angle < endAngle; angle += angleStep) { CGPoint ellipsePoint = [self ellipsePointForAngle:angle withCenter:center xRadius:xRadius yRadius:yRadius]; [ellipseSegment addLineToPoint:ellipsePoint]; } CGPoint lastEllipsePoint = [self ellipsePointForAngle:endAngle withCenter:center xRadius:xRadius yRadius:yRadius]; [ellipseSegment addLineToPoint:lastEllipsePoint]; return ellipseSegment; } + (UIBezierPath *)bezierPathWithOvalInRect:(CGRect)rect startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle { return [UIBezierPath bezierPathWithOvalInRect:rect startAngle:startAngle endAngle:endAngle angleStep:M_PI/20.0f]; } + (CGPoint)ellipsePointForAngle:(CGFloat)angle withCenter:(CGPoint)center xRadius:(CGFloat)xRadius yRadius:(CGFloat)yRadius { CGFloat x = center.x + xRadius * cosf(angle); CGFloat y = center.y - yRadius * sinf(angle); return CGPointMake(x, y); } @end 

您将不得不使用addQuadCurveToPoint:controlPoint:而不是bezierPathWithOvalInRect.

方法定义如下: –

 - (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint 

即CGPoint是两个参数的参数(input)。

在调用addQuadCurveToPoint之前,你还必须使用moveToPoint:来设置addQuadCurveToPoint ,它将作为当前点(正如你可以在方法中看到它们没有起点的参数一样)。

在你的情况下,你会有

1> x,y作为你的出发点

2> x +宽度和y +高度作为终点

你不需要在这里angular度,或者你可以实现你的逻辑使用的angular度。上传图像,使事情清楚。

这里是描述起点,终点和控制点的图像

    Interesting Posts