UIBezierPath с несколькими дугами

Хиииии

Я пытаюсь нарисовать в представлении дугу с динамической шириной. введите здесь описание изображения

Я построил МАССИВ с несколькими UIBezierPath с дугами, а затем рисую одну за другой. это код:

    - (void)drawRect:(CGRect)rect
    {
    // Drawing code

    CGFloat radious;
    if (self.bounds.size.width < self.bounds.size.height) {
        radious = self.bounds.size.width / 2;
    }
    else{
        radious = self.bounds.size.height / 2;
    }

    float oneGradeInRadians = (float)(2 * M_PI) / 360.f;
    float radiandToDraw = (float)self.finalAngleRadians - self.initialAngleRadians;
    float splitMeasure = oneGradeInRadians;
    int numberOfArcs = radiandToDraw / splitMeasure;

    NSMutableArray *arrayOfBeziersPaths = [NSMutableArray arrayWithCapacity:numberOfArcs];
    for (int i = 0; i < numberOfArcs; i++) {

         float startAngle = self.initialAngleRadians + (i * splitMeasure);
         float endAngle = self.initialAngleRadians +((i + 1) * splitMeasure);
         UIBezierPath *bezierPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.frame.size.width/2, self.frame.size.height/2) radius:radious - self.widthLine.floatValue startAngle:startAngle endAngle:endAngle clockwise:YES];
        bezierPath.lineWidth = self.widthLine.floatValue + i/20;
        float hue = (float)(i / 3.f);
        UIColor *color = [UIColor colorWithHue:hue/360.0 saturation:1 brightness:1 alpha:1];
        [color setStroke];

        [arrayOfBeziersPaths addObject:bezierPath];
    }



    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetLineJoin(context, kCGLineJoinMiter);
    //We saved the context
    CGContextSaveGState(context);
    for (int i = 0; i < numberOfArcs; i++) {
        [(UIBezierPath *)[arrayOfBeziersPaths objectAtIndex:i] stroke];
        [(UIBezierPath *)[arrayOfBeziersPaths objectAtIndex:i] fill];
     }

    //Restore the contex
    CGContextRestoreGState(context);
    }

Таким образом, я получаю правильную форму, но также получаю раздражающие линии между дугами: введите здесь описание изображения

Я думаю, что проблема может заключаться в изменении свойства между дугами, но я полностью потерялся, или, может быть, есть другой лучший способ построить это.

Я попытался создать несколько путей UIBezierPath и добавил их в уникальный UIBezierPath, а затем заполнил этот путь. Я не получил надоедливых линий, но проблема в том, что я не могу изменить ширину линии, поэтому я не могу получить тот же эффект.

Есть идеи? Спасибо


person xarly    schedule 03.02.2014    source источник


Ответы (2)


не создавайте много таких путей. просто создайте линии two arcs (inner circle, exterior circle) и two straight, соединяющие концы. затем заполните путь.

Добавьте приведенный ниже код в viewDidLoad пустого viewController и проверьте.

- (void)viewDidLoad
{
    [super viewDidLoad];

    CGFloat k =0.5522847498;
    UIBezierPath *path =[UIBezierPath bezierPath];
    CGFloat radius=130;
    [path addArcWithCenter:CGPointMake(0, 0) radius:radius startAngle:M_PI_2 endAngle:M_PI clockwise:NO];

    CGFloat start=10;
    CGFloat increment=5;
    [path addLineToPoint:CGPointMake(-radius-start, 0)];
    [path addCurveToPoint:CGPointMake(0, -radius-start-increment) controlPoint1:CGPointMake(-radius-start, -(radius +start)*k) controlPoint2:CGPointMake(-(radius+start)*k, -radius-start-increment)];
    [path addCurveToPoint:CGPointMake(radius+start+2*increment, 0) controlPoint1:CGPointMake((radius+start+increment)*k, -radius-start-increment) controlPoint2:CGPointMake(radius+start+2*increment, (-radius-start-increment)*k)];
    [path addCurveToPoint:CGPointMake(0, radius+start+3*increment) controlPoint1:CGPointMake(radius+start+2*increment, (radius+start+2*increment)*k) controlPoint2:CGPointMake((radius+start+2*increment)*k,radius+start+3*increment)];
    [path addLineToPoint:CGPointMake(0,radius)];

    CAShapeLayer *layer =[CAShapeLayer layer];
    [layer setFrame:CGRectMake(150, 200, 300, 300)];
    [layer setFillColor:[UIColor greenColor].CGColor];
    [layer setStrokeColor:[UIColor blackColor].CGColor];
    [layer setPath:path.CGPath];
    [self.view.layer addSublayer:layer];
}

Это дало результат, например, введите описание изображения здесь

person santhu    schedule 03.02.2014
comment
Это удивительное приближение и очень полезное, но моя проблема в том, что я хочу, чтобы пользователь увеличивал или уменьшал рисование по часовой стрелке. Это не решение, но вы дали мне отличный способ узнать это. Большое спасибо - person xarly; 04.02.2014

Проблема здесь в том, что вы выбрали сумасшедший подход к рисованию формы, которая вам нужна. Если вы посмотрите на него, то увидите, что на самом деле это заполненная область, ограниченная снаружи дугой окружности, а с внутренней стороны спиралью.

Поэтому вам нужно создать один NSBezierPath, добавить к нему внешнюю дугу окружности, затем добавить линию в начало вашей спирали, добавить спираль (вы захотите аппроксимировать ее сегментами Безье) и, наконец, вызвать -closePath. После этого вы можете -fill пройти путь, и вы получите хорошо выглядящий результат, а не беспорядок, который вы видели выше.

person alastair    schedule 04.02.2014