2013-07-17 1 views
1

ОК, поэтому мне нужен был округленный треугольник. Итак, я использовал метод, подобный тому, что я использовал в других программах рисования векторов. Нарисуйте треугольник и используйте штрих, чтобы создать закругленные углы. Работал как шарм, пока мне не понадобилось уменьшать альфа цвета, используемого для заполнения и инсульта UIBezierPath. По какой-то причине я продолжаю получать этот контур вставки, который не такой же, как у Fill и Stroke. Как-то альфа-значение не соблюдается. Может быть, я что-то с видом глупо здесь, но попробовать, как я мог, я не могу получить треугольник все один цвет с альфа-значением меньше 1. Это то, что я получаю: enter image description hereНе может показаться, что он избавился от строки в UIBezierPath

И Heres простой код:

- (void)drawRect:(CGRect)rect 
{ 
    UIBezierPath *path = [UIBezierPath bezierPath]; 
    [path moveToPoint: CGPointMake(63.5, 10.5)]; 
    [path addLineToPoint: CGPointMake(4.72, 119.5)]; 
    [path addLineToPoint: CGPointMake(122.28, 119.5)]; 
    [path addLineToPoint: CGPointMake(63.5, 10.5)]; 
    [path closePath]; 
    path.miterLimit = 7; 

    path.lineCapStyle = kCGLineCapRound; 

    path.lineJoinStyle = kCGLineJoinRound; 
    path.lineWidth = 8; 

    UIColor *whiteAlph5 = [UIColor colorWithWhite:0.6 alpha:0.5]; 

    [whiteAlph5 setFill]; 
    [whiteAlph5 setStroke]; 


    [path fill]; 
    [path stroke]; 
} 

Я не могу понять, почему линия будет ничего, кроме «whiteAlpha5», если это единственный цвет, я установил как для заливки и обводки. Я полагаю, что могу просто нарисовать округленный треугольник, добавив кривые к углам, но мне просто интересно, почему это происходит. Спасибо заранее ...

ответ

2

Линия состоит в том, что ваш штрих и ваша заливка рисуются на одинаковые пиксели. Поскольку и ход, и заполнение частично прозрачны, цвета накапливаются.

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

Вот интерфейс для категории, которая создает путь с изложением скругленный многоугольник:

@interface UIBezierPath (MyRoundedPolygon) 

+ (UIBezierPath *)my_roundedPolygonWithSides:(int)sides center:(CGPoint)center 
    vertexRadius:(CGFloat)vertexRadius cornerRadius:(CGFloat)cornerRadius 
    rotationOffset:(CGFloat)rotationOffset; 

@end 

Вот реализация:

@implementation UIBezierPath (MyRoundedPolygon) 

static CGPoint vertexForPolygon(int sides, CGPoint center, CGFloat circumradius, CGFloat index) { 
    CGFloat angle = index * 2 * M_PI/sides; 
    return CGPointMake(center.x + circumradius * cosf(angle), 
     center.y + circumradius * sinf(angle)); 
} 

+ (UIBezierPath *)my_roundedPolygonWithSides:(int)sides center:(CGPoint)center 
    vertexRadius:(CGFloat)vertexRadius cornerRadius:(CGFloat)cornerRadius 
    rotationOffset:(CGFloat)rotationOffset 
{ 
    CGFloat circumradius = vertexRadius + cornerRadius; 
    CGPoint veryLastVertex = vertexForPolygon(sides, center, circumradius, rotationOffset - 1); 
    CGPoint currentVertex = vertexForPolygon(sides, center, circumradius, rotationOffset); 
    CGMutablePathRef cgpath = CGPathCreateMutable(); 
    CGPathMoveToPoint(cgpath, NULL, (veryLastVertex.x + currentVertex.x)/2, 
     (veryLastVertex.y + currentVertex.y)/2); 
    for (CGFloat i = 0; i < sides; ++i) { 
     CGPoint nextVertex = vertexForPolygon(sides, center, circumradius, 
      i + 1 + rotationOffset); 
     CGPathAddArcToPoint(cgpath, NULL, currentVertex.x, currentVertex.y, 
      nextVertex.x, nextVertex.y, cornerRadius); 
     currentVertex = nextVertex; 
    } 
    CGPathCloseSubpath(cgpath); 
    UIBezierPath *path = [self bezierPathWithCGPath:cgpath]; 
    CGPathRelease(cgpath); 
    return path; 
} 

@end 

Вот как вы его используете:

@implementation MyView 

- (void)drawRect:(CGRect)rect 
{ 
    CGRect bounds = self.bounds; 
    CGPoint center = CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds)); 
    UIBezierPath *path = [UIBezierPath my_roundedPolygonWithSides:3 center:center 
     vertexRadius:70 cornerRadius:8 rotationOffset:0.25]; 
    [[UIColor colorWithWhite:0.6 alpha:0.5] setFill]; 
    [path fill]; 
} 

@end 

И вот результат:

rounded triangle

Обратите внимание, что установка rotationOffset на 0,25 повернута треугольником на четверть оборота. Установка его на ноль даст вам правый треугольник.

+0

Aha! Они были перекрывающимися. Благодарю. –

4

Если у вас должен быть инсульт, измените свой вызов на [UIBezierPath stroke] так:

[path fill]; 
[path strokeWithBlendMode:kCGBlendModeCopy alpha:1.0]; 

Это должно достичь желаемого эффекта (я думаю - не был в состоянии проверить это)

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

Если вам нужна визуальная демонстрация того, что я имею в виду, вы можете сделать это в Photoshop. Создайте новое изображение с черным фоном и создайте над ним новый слой, установите на 50% непрозрачность. Нарисуйте на нем белый квадрат (который будет выглядеть серым из-за непрозрачности). Затем, не меняя слоев, проведите через него линию. Вы не увидите линию, потому что она заменяет существующий цвет - это то, что вы ожидали от своего кода. Затем добавьте еще один слой над ним, также установите 50% непрозрачность. Нарисуйте линию на этом слое через квадрат. Вы увидите линию ярче серого цвета. Это аддитивное, белое перекрытие на обоих слоях - эффект, который создает ваш код.

+0

Это подход, который я бы принял. – ipmcc