如何快速使用贝塞尔曲线路径创建大小不同的图饼?

ees*_*osu 2 graphic ios uibezierpath quartz-core swift

我想制作一个具有8个相等切片的漂亮图形饼图,可以根据一个Int或类似的东西进行单独缩放或调整大小。如下所示,只是将所有切片均等地切割:

在此处输入图片说明

我曾在Objective-C中尝试过此方法,但它仅占一小部分:

  -(CAShapeLayer *)createPieSlice {
    CAShapeLayer *slice = [CAShapeLayer layer];
    slice.fillColor = [UIColor redColor].CGColor;
    slice.strokeColor = [UIColor blackColor].CGColor;
    slice.lineWidth = 3.0;

    CGFloat angle = DEG2RAD(-60.0);
    CGPoint center = CGPointMake(100.0, 100.0);
    CGFloat radius = 100.0;

    UIBezierPath *piePath = [UIBezierPath bezierPath];
    [piePath moveToPoint:center];

    [piePath addLineToPoint:CGPointMake(center.x + radius * cosf(angle), center.y + radius * sinf(angle))];

    [piePath addArcWithCenter:center radius:radius startAngle:angle endAngle:DEG2RAD(60.0) clockwise:YES];

    //  [piePath addLineToPoint:center];
    [piePath closePath]; // this will automatically add a straight line to the center
    slice.path = piePath.CGPath;

    return slice;
    }
Run Code Online (Sandbox Code Playgroud)

如何快速获得该图?

Dun*_*n C 5

将问题分解为逻辑部分。

您有不同弧形宽度的楔形。所有这些半径需要累加一个完整的圆。我认为它们代表的是总和为100%的分数。您要特定的订单吗?如果是这样,请按所需顺序映射分数,以使分数总计达到100%。

然后编写以零角度开始的代码,并创建指定分数2?的弧。每个开始于上一个结束。根据所需数据分配合适的半径。

现在,编写在UIBezierPath中创建封闭路径段的代码。

编辑

您已经澄清了,并告诉我们,您总是想要8个宽度相同但半径不同的切片。

因此,您需要编写采用8个输入值并将其绘制为8个具有不同半径值的圆弧的代码。

假设您的输入值是一个从0到1的浮点数组。在零处,楔形的大小为零。值为1.0时,它是适合您的视图的最大圆形尺寸(正方形视图的一半宽度)。

因此,您将创建一个由8个浮点数组成的数组:

var fractions = [0.5, 0.7, 0.3, 0.1, 1.0 .6, .2, .9]
Run Code Online (Sandbox Code Playgroud)

创建具有8条弧线的贝塞尔曲线的代码可能如下所示:

let pi = 3.1415826
let largestRadius = myView.width/2

let piePath = UIBezierPath()
for (index, afloat) in fractions
{
  let startAngle = Double(index) / fractions.count * 2 * pi
  let endAngle = Double(index+1) / fractions.count * 2 * pi
  let thisRadius = largestRadius * afloat
  let center = CGPointMake( myView.width/2, myView.height/2)
  piePath.moveToPoint(center)

  piePath.addArcWithCenter(center,
    radius: thisRadius,
    startAngle: startAngle,
    endAngle: endAngle,
    clockwise: true)
  piePath.lineToPoint(center)
  piePath.closePath()
}
Run Code Online (Sandbox Code Playgroud)

认为上面的代码会创建8条封闭的扇形路径,但我并不乐观。在第一个moveToPoint调用和弧调用之间可能需要添加lineToPoint调用。

编辑#2:

自从我学习Swift以来,我决定以此作为练习,并编写了一个示例项目,该示例项目使用形状层和从UIBezierPath创建的自定义路径生成饼图,如上所述。您可以在github上找到示例项目:Github上的PieCharts项目