Draw an ellipse with a start and end angle in Objective-C

I am writing an iPad application in which I pass in XML objects that represent shapes in graphics on the screen. One of the objects I'm trying to do is arcs. Essentially, these arcs provide me with a bounding box, as well as a start and end angle.

Specified Attributes:

  • x
  • at
  • width
  • Height
  • Startangle
  • endAngle

With these values, I need to draw an arc (which is essentially part of the ellipse). I can not use the following:

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

. , , . , , . , , , , .

+5
3

, , , .

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);

. , , .

+9

.

#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
+3

addQuadCurveToPoint:controlPoint: bezierPathWithOvalInRect.

: -

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

CGPoint - () .

You will also need to set the starting point with moveToPoint:before the call addQuadCurveToPoint, which will act as the current point (since you can see that their starting point is not a parameter in the method).

In your case you will have

1> x, y as a starting point

2> x + width and y + height as the endpoint

you don't need angles here, or you can implement your logic for using angles. Upload the image so that everything is clear.

Here is the image describing the start point, end point and control point

+2
source

All Articles