绘制椭圆与目标C的开始和结束角度(Draw ellipse with start and end a

2019-07-29 10:33发布

我写的iPad应用程序中,我渲染代表的形状到屏幕上的图形的XML对象。 一个我试图渲染的对象是弧线。 从本质上讲,这些弧为我提供了一个边框,以及开始和结束的角度。

鉴于属性:

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

使用这些值,我需要画圆弧(其本质上是一个椭圆形的一部分)。 我不能使用以下命令:

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

因为它绘制一个完整的椭圆。 基本上我需要以上,但需要考虑的开始和结束角度被显示在椭圆形的,从而仅一部分。 我想这将涉及要么绘制三次Bezier曲线或二次贝塞尔曲线。 问题是我不知道如何计算的起点,终点,或者用我提供的信息控制点。

Answer 1:

你也许可以实现您通过设置椭圆的绘制围绕剪切路径想要的东西。

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

对于剪辑的确切半径并不重要。 它需要所以只夹在两端的椭圆形,而不是通过所需的电弧足够大。



Answer 2:

此类别会有所帮助。

#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


Answer 3:

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

该方法的定义是: -

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

即CGPoint是两者的参数的参数(输入)。

您还必须设置使用起点moveToPoint:致电前addQuadCurveToPoint这将作为当前点作用(正如你可以看到他们在方法,没有起点为参数)。

你的情况,你将有

1> X,Y作为起点

2> X +宽度和y +高度端点

你不要在这里需要的角度也可以实现你的逻辑使用angles.Am的图片上传,使事情清楚。



文章来源: Draw ellipse with start and end angle in Objective-C