gpt4 book ai didi

ios - CALayer clip CGContextAddArc(制作 donut 幻灯片/饼图)

转载 作者:可可西里 更新时间:2023-11-01 04:23:45 31 4
gpt4 key购买 nike

我正在尝试学习和理解 CoreGraphics。我想做的是制作饼图。

饼图工作正常并且看起来很棒,但我在剪裁内圆时遇到了问题。

这是饼图中每张幻灯片的代码:

CGPoint center = CGPointMake((self.bounds.size.width/2) + self.centerOffset, (self.bounds.size.height/2) - self.centerOffset);
CGFloat radius = MIN(center.x, center.y) - 25;
radius *= self.pieScale;

CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, center.x, center.y);

CGPoint p1 = CGPointMake(center.x + radius * cosf(self.startAngle), center.y + radius * sinf(self.startAngle));
CGContextAddLineToPoint(ctx, p1.x, p1.y);

int clockwise = self.startAngle > self.endAngle;
CGContextAddArc(ctx, center.x, center.y, radius, self.startAngle, self.endAngle, clockwise);
CGContextClosePath(ctx);

CGContextMoveToPoint(ctx, center.x, center.y);
CGContextAddArc(ctx, center.x, center.y, radius*0.5, self.startAngle, self.endAngle, clockwise);

CGContextSetFillColorWithColor(ctx, self.fillColor.CGColor);
CGContextSetStrokeColorWithColor(ctx, self.strokeColor.CGColor);
CGContextSetLineWidth(ctx, self.strokeWidth);

self.pathRef = CGContextCopyPath(ctx);
CGContextDrawPath(ctx, kCGPathFillStroke);

我现在的馅饼是这样的:

http://cl.ly/image/1v1D3l3O0u3T

我设法通过绘制一条半径较小的新路径来添加一个内圆。

我尝试用 CGContextClip(ctx); 剪辑第二条路径,但只留下像这样的内圈:

http://cl.ly/image/2G402n3G3J2G

对我来说有点道理为什么会这样,但我想不出我还应该做什么。

编辑:

代码现在看起来像:

CGPoint center = CGPointMake((self.bounds.size.width/2) + self.centerOffset, (self.bounds.size.height/2) - self.centerOffset);
CGFloat radius = MIN(center.x, center.y) - 25;
radius *= self.pieScale;
CGPoint p1 = CGPointMake(center.x + radius * cosf(self.startAngle), center.y + radius * sinf(self.startAngle));
int clockwise = self.startAngle > self.endAngle;

CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, center.x, center.y);

CGContextAddLineToPoint(ctx, p1.x, p1.y);
CGContextAddArc(ctx, center.x, center.y, radius, self.startAngle, self.endAngle, clockwise);
CGContextClosePath(ctx);

CGContextMoveToPoint(ctx, center.x, center.y);
CGContextAddArc(ctx, center.x, center.y, radius*0.5, self.startAngle, self.endAngle, !clockwise);


CGContextSetFillColorWithColor(ctx, self.fillColor.CGColor);
CGContextSetStrokeColorWithColor(ctx, self.strokeColor.CGColor);
CGContextSetLineWidth(ctx, self.strokeWidth);

self.pathRef = CGContextCopyPath(ctx);
CGContextDrawPath(ctx, kCGPathFillStroke);

看起来像:

enter image description here

所有绘图代码:

我的类是 CALayer 的子类。此代码在饼图上绘制一个切片。

-(void)drawInContext:(CGContextRef)ctx
{
CGPoint center = CGPointMake((self.bounds.size.width/2) + self.centerOffset, (self.bounds.size.height/2) - self.centerOffset);
CGFloat radius = MIN(center.x, center.y) - 25;
radius *= self.pieScale;
int clockwise = self.startAngle > self.endAngle;

/* Clipping should be done first so the next path(s) are not creating the clipping mask */
CGContextMoveToPoint(ctx, center.x, center.y);
CGContextAddArc(ctx, center.x, center.y, radius*0.5, self.startAngle, self.endAngle, !clockwise);
//CGContextClipPath(ctx);
CGContextClip(ctx);

/* Now, start drawing your graph and filling things in... */
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, center.x, center.y);

CGPoint p1 = CGPointMake(center.x + radius * cosf(self.startAngle), center.y + radius * sinf(self.startAngle));

CGContextAddLineToPoint(ctx, p1.x, p1.y);
CGContextAddArc(ctx, center.x, center.y, radius, self.startAngle, self.endAngle, clockwise);
CGContextClosePath(ctx);


CGContextSetFillColorWithColor(ctx, self.fillColor.CGColor);
CGContextSetStrokeColorWithColor(ctx, self.strokeColor.CGColor);
CGContextSetLineWidth(ctx, self.strokeWidth);

self.pathRef = CGContextCopyPath(ctx);
CGContextDrawPath(ctx, kCGPathFillStroke);

// LABELS
UIGraphicsPushContext(ctx);
CGContextSetFillColorWithColor(ctx, self.labelColor.CGColor);

CGFloat distance = [self angleDistance:(self.startAngle * 180/M_PI) angle2:(self.endAngle * 180/M_PI)];
CGFloat arcDistanceAngle = distance * M_PI/180;
CGFloat arcCenterAngle = self.startAngle + arcDistanceAngle/2;

CGPoint labelPoint = CGPointMake(center.x + radius * cosf(arcCenterAngle), center.y + radius * sinf(arcCenterAngle));


/*
Basic drawing of lines to labels.. Disabled for now..
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, labelPoint.x, labelPoint.y);
*/

if(labelPoint.x <= center.x)
labelPoint.x -= 50;
else
labelPoint.x += 5;

if(labelPoint.y <= center.y)
labelPoint.y -= 25;



/*
Basic drawing of lines to labels.. Disabled for now..
CGContextAddLineToPoint(ctx, labelPoint.x, labelPoint.y);
CGContextClosePath(ctx);

CGContextSetFillColorWithColor(ctx, self.fillColor.CGColor);
CGContextSetStrokeColorWithColor(ctx, self.strokeColor.CGColor);
CGContextSetLineWidth(ctx, self.strokeWidth);
CGContextDrawPath(ctx, kCGPathFillStroke);
*/

[self.labelString drawAtPoint:labelPoint forWidth:50.0f withFont:[UIFont systemFontOfSize:18] lineBreakMode:NSLineBreakByClipping];
UIGraphicsPopContext();

}

最佳答案

如果您不想拥有饼图的中心(即制作所谓的 donut 车),那么我建议您创建独立的 donut 部分的形状,而不是制作饼图切片并遮住中心。

可能首先想到的是用两条直线和两条半径不同但中心坐标相同的圆弧共同创建该线段。幸运的是,在 Core Graphics 中有更简单的方法来制作这种形状。这种形状实际上只是一个角度和另一个角度之间的单一弧形,但更粗。我已经在 this answer 中解释了这一切(针对“从圆形或 donut 中绘制线段”的问题),但这里只是对 donut 线段形状的简短解释。

第 1 步:创建圆弧

创建将位于 donut 段中心的圆弧(下图中的橙色线)。半径将为 (r<sub>max</sub> + r<sub>min</sub>) / 2 .

enter image description here

CGMutablePathRef arc = CGPathCreateMutable();
CGPathMoveToPoint(arc, NULL,
startPoint.x, startPoint.y);
CGPathAddArc(arc, NULL,
centerPoint.x, centerPoint.y,
radius,
startAngle,
endAngle,
YES);

第 2 步:画弧线

通过描边圆弧创建最终的 donut 段形状。这个功能对你来说可能看起来很神奇,但这就是在 Core Graphics 中找到隐藏宝藏的感觉。它将以特定的描边宽度描边路径。 “线帽”和“线连接”控制形状的开始和结束的外观以及路径组件之间的连接方式(此形状中只有一个组件)。

enter image description here

CGFloat lineWidth = 10.0; // any radius you want
CGPathRef donutSegment =
CGPathCreateCopyByStrokingPath(arc, NULL,
lineWidth,
kCGLineCapButt,
kCGLineJoinMiter, // the default
10); // 10 is default miter limit

第三步:没有第三步(嗯,有填充+描边)

像填充饼图一样填充此形状。 (上图 2 中使用了浅灰色和黑色)。

CGContextRef c = UIGraphicsGetCurrentContext();
CGContextAddPath(c, donutSegment);
CGContextSetFillColorWithColor(c, [UIColor lightGrayColor].CGColor);
CGContextSetStrokeColorWithColor(c, [UIColor blackColor].CGColor);
CGContextDrawPath(c, kCGPathFillStroke);

关于ios - CALayer clip CGContextAddArc(制作 donut 幻灯片/饼图),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18614376/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com