Draw ellipse with start and end angle in Objective-C

前端 未结 3 1305
轻奢々
轻奢々 2021-02-09 06:32

I am writing an iPad app in which I am rendering XML objects that represent shapes into graphics on the screen. One of the objects I am trying to render is arcs. Essentially the

相关标签:
3条回答
  • 2021-02-09 06:53

    This category will help.

    #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
    
    0 讨论(0)
  • 2021-02-09 06:55

    You will have to use addQuadCurveToPoint:controlPoint:instead of bezierPathWithOvalInRect.

    The method definition is as:-

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

    that is CGPoint are the arguments(input) for both the parameters.

    You will also have to set the start point using moveToPoint:before calling addQuadCurveToPoint which will act as current point(As you can see their's no start point as parameter in the method).

    In your case you will have

    1>x,y as your starting point

    2>x+width and y+height as endpoint

    you don't need angles here or you can implement your logic to use the angles.Am uploading an image to make thing clear.

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

    0 讨论(0)
  • 2021-02-09 07:05

    You can probably achieve what you want by setting up a clip path around the drawing of the ellipse.

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

    The exact radius for the clipping isn't important. It needs to be big enough so it only clips the ellipse at the ends, not through the desired arc.

    0 讨论(0)
提交回复
热议问题