在iOS中绘制一个带有颜色的三角形

3
我希望能画出一个具有给定线条颜色、线条粗细和填充颜色的三角形。 但不知道为什么无法正确地填充三角形。每次都会将三角形周围的整个区域填充。
这是我的代码:
+ (UIImage *) drawColorTriangleWithBorderWidth:(int)Width Height:(int)Height R:(int)R G:(int)G B:(int)B A:(int)A BorderR:(int)BR BorderG:(int)BG BorderB:(int)BB BorderA:(int)BA Thickness:(CGFloat)thickness {

    if ( Width == 0 || Height == 0) return nil;

    float de = thickness/2.0;

    UIGraphicsBeginImageContext(CGSizeMake(Width+de, Height+de));
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextBeginPath(context);    

    CGFloat rr = 1.0*R/255.0; if ( rr > 1.0) rr = 1.0;
    CGFloat gg = 1.0*G/255.0; if ( gg > 1.0) gg = 1.0;
    CGFloat bb = 1.0*B/255.0; if ( bb > 1.0) bb = 1.0;
    CGFloat aa = 1.0*A/100.0; if ( aa > 1.0) aa = 1.0;

    CGFloat brr = 1.0*BR/255.0; if ( brr > 1.0) brr = 1.0;
    CGFloat bgg = 1.0*BG/255.0; if ( bgg > 1.0) bgg = 1.0;
    CGFloat bbb = 1.0*BB/255.0; if ( bbb > 1.0) bbb = 1.0;
    CGFloat baa = 1.0*BA/100.0; if ( baa > 1.0) baa = 1.0;

    CGContextSetLineCap(context, kCGLineCapSquare);
    CGContextSetRGBFillColor(context, rr, gg, bb, aa);
    CGContextSetLineWidth(context, thickness);
    CGContextSetRGBStrokeColor(context, brr, bgg, bbb, baa);

    CGContextMoveToPoint(context, Width/2.0, de);
    CGContextAddLineToPoint(context, de, Height-de);
    CGContextAddLineToPoint(context, Width-de, Height-de);
    CGContextAddLineToPoint(context, Width/2.0, de);
    CGContextDrawPath(context, kCGPathFillStroke);

    UIImage * image = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return image;
}

谁能帮助我? 谢谢。


1
注意:CGFloat rr = 1.0*R/255.0; if ( rr > 1.0) rr = 1.0; 可以更简单地写成:CGFloat rr = MIN(R/255.0, 1.0); - zaph
不要使用最后一个CGContextAddLineToPoint,而是使用CGContextClosePath - Wain
为什么要使用大写字母的变量? - fnc12
2个回答

2

在添加不同的路径后,您需要关闭该路径:

CGContextMoveToPoint(context, Width/2.0, de);
CGContextAddLineToPoint(context, de, Height-de);
CGContextAddLineToPoint(context, Width-de, Height-de);
CGContextClosePath(context);
CGContextFillPath(context);

CGContextFillPath() 的文档明确说明:“Quartz 将每个子路径视为通过调用 CGContextClosePath 来关闭。” - 因此,不需要关闭路径。 - Martin R
好的,填充无论如何都是必要的。 - Antonio MG
如果您想要填充和描边路径,必须使用CGContextDrawPath(..., kCGPathFillStroke)(请参考https://dev59.com/EXHYa4cB1Zd3GeqPReox#16462849)。 - Martin R

1
这是使用OP发布的代码实现的:

UIImage *image = [[self class] drawColorTriangleWithBorderWidth:100 Height:100 R:200 G:0 B:0 A:200 BorderR:0 BorderG:0 BorderB:200 BorderA:100 Thickness:3.0];

[UIImageJPEGRepresentation(image, 1.0) writeToFile:@"/Users/dan/Desktop/UIImage.jpg" atomically:YES];

生成这张图片:
在此输入图片描述

CGContextFillPath() 的文档明确说明:“Quartz 将每个子路径视为通过调用 CGContextClosePath 来关闭。” - 因此,不需要关闭路径。 - Martin R
1
@Martin 如果我画了三角形的两条边并描边,那么第三条边也会被描边吗?我的理解是CGContextClosePath在填充时不需要,实际上这个引用只出现在填充例程的文档中。这是否意味着填充不需要添加三角形的第三条边? - zaph
首先,如果您想要填充和描边路径,必须使用CGContextDrawPath(context, kCGPathFillStroke)(请参见https://dev59.com/EXHYa4cB1Zd3GeqPReox#16462849)。您是正确的,关闭路径对于完整的描边是必要的。但问题在于问题报告中指出的“三角形周围的整个区域也被填充了”。也许与`CGContextFillPath()`不同,`kCGPathFillStroke`不会隐式地关闭路径... - Martin R

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接