在Objective中绘制具有开始和结束角度的椭圆
我正在编写一个iPad应用程序,在该应用程序中,我将表示形状的XML对象呈现在屏幕上的图形中。 我想渲染的一个对象是弧线。 基本上这些弧为我提供了一个边界矩形以及一个开始和结束角度。
给定属性:
有了这些值,我需要绘制弧(它基本上是椭圆的一部分)。 我不能使用以下内容:
UIBezierPath *arc = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(x, y, width, height)];
[UIColor blackColor] setStroke];
[arc stroke];
因为它绘制了一个完整的椭圆。 基本上我需要上面的,但它需要考虑开始和结束角度,因此只显示椭圆的一部分。 我认为这将涉及绘制三次贝塞尔曲线或二次贝塞尔曲线。 问题是我不知道如何用我给出的信息计算出发点,终点或控制点。
您可以通过在椭圆的绘图周围设置剪辑路径来达到您想要的效果。
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是两个参数的参数(输入)。
您还必须使用moveToPoint:
设置起点moveToPoint:
在调用addQuadCurveToPoint
之前,它将充当当前点(您可以在方法中看到它们的无起点作为参数)。
在你的情况下,你会有
1> x,y作为你的出发点
2> x +宽度和y +高度作为终点
你不需要在这里角度,或者你可以实现你的逻辑来使用角度。上传图片使事情变得清晰。
链接地址: http://www.djcxy.com/p/61681.html上一篇: Draw ellipse with start and end angle in Objective
下一篇: How to define a circle shape in an android xml drawable file?