Core Graphics复杂的形状在笔画填充内(Core Graphics complicated shape inside a stroke fill)

编程入门 行业动态 更新时间:2024-10-24 13:32:16
Core Graphics复杂的形状在笔画填充内(Core Graphics complicated shape inside a stroke fill)

我正在尝试使用Core Graphics在我的应用程序中绘制一些图形,并且我正在理解将多个图形合并为一个的最佳做法。

这是我想要结束的形状(包括颜色)。

圈子http://www.myquapps.com/help/lvl1Circle1.png

到目前为止,我已经用正确的笔画绘制了一个相同大小的圆圈,如下所示: -

CGContextRef ctx = UIGraphicsGetCurrentContext(); CGContextClearRect(ctx, rect); CGContextSetRGBFillColor(ctx, 0, 0, 0, 1); CGFloat red[4] = {1.0f, 0.0f, 0.0f, 1.0f}; CGContextSetStrokeColor(ctx, red); CGContextSetLineWidth(ctx, 18); CGContextStrokeEllipseInRect(ctx, CGRectMake(9, 9, 232, 232)); CGContextFillPath(ctx);

任何帮助在这里将不胜感激! 这是我第一次使用Core Graphics,它看起来正是我需要的!

I am attempting to draw some shapes in my app using Core Graphics and I am having some issues understanding the best practices for masking multiple shapes into one.

This is the shape I want to end up with (including colours).

Circle http://www.myquapps.com/help/lvl1Circle1.png

So far I have drawn a circle the same size with the correct stroke like so:-

CGContextRef ctx = UIGraphicsGetCurrentContext(); CGContextClearRect(ctx, rect); CGContextSetRGBFillColor(ctx, 0, 0, 0, 1); CGFloat red[4] = {1.0f, 0.0f, 0.0f, 1.0f}; CGContextSetStrokeColor(ctx, red); CGContextSetLineWidth(ctx, 18); CGContextStrokeEllipseInRect(ctx, CGRectMake(9, 9, 232, 232)); CGContextFillPath(ctx);

Any help here would be greatly appreciated! This is my first run-in with Core Graphics and it looks to be exactly what I need!

最满意答案

带了我一下,但你走了(所有的贝塞尔路径都是实例变量):

编辑:使圆的内部透明,但支撑自己,这得到快速难看!

#define LARGE_RADIUS 200 #define SMALL_RADIUS 160 #define RADIANS(degrees) ((degrees) / (180.0 / M_PI)) @implementation MyView { UIBezierPath *largeCircle; UIBezierPath *orangeWedge; UIBezierPath *yellowWedge; UIBezierPath *greenWedge; UIBezierPath *whiteCircle; UIImage *image; void *_imageData; } -(void) createPaths { largeCircle = [UIBezierPath bezierPathWithArcCenter:self.center radius:LARGE_RADIUS startAngle:0 endAngle:RADIANS(360) clockwise:YES]; whiteCircle = [UIBezierPath bezierPathWithArcCenter:self.center radius:SMALL_RADIUS startAngle:0 endAngle:RADIANS(360) clockwise:YES]; orangeWedge = [UIBezierPath bezierPath]; [orangeWedge moveToPoint:self.center]; double startAngle = RADIANS(45); double endAngle = RADIANS(135); [orangeWedge addLineToPoint:CGPointMake(sin(startAngle) + self.center.x, cos(startAngle) + self.center.y)]; [orangeWedge addArcWithCenter:self.center radius:LARGE_RADIUS startAngle:startAngle endAngle:endAngle clockwise:YES]; [orangeWedge addLineToPoint:self.center]; startAngle = RADIANS(60); endAngle = RADIANS(120); yellowWedge = [UIBezierPath bezierPath]; [yellowWedge moveToPoint:self.center]; [yellowWedge addLineToPoint:CGPointMake(sin(startAngle) + self.center.x, cos(startAngle) + self.center.y)]; [yellowWedge addArcWithCenter:self.center radius:LARGE_RADIUS startAngle:startAngle endAngle:endAngle clockwise:YES]; [yellowWedge addLineToPoint:self.center]; startAngle = RADIANS(75); endAngle = RADIANS(105); greenWedge = [UIBezierPath bezierPath]; [greenWedge moveToPoint:self.center]; [greenWedge addLineToPoint:CGPointMake(sin(startAngle) + self.center.x, cos(startAngle) + self.center.y)]; [greenWedge addArcWithCenter:self.center radius:LARGE_RADIUS startAngle:startAngle endAngle:endAngle clockwise:YES]; [greenWedge addLineToPoint:self.center]; } -(void) drawPaths { [[UIColor blackColor] setStroke]; [[UIColor redColor] setFill]; [largeCircle fill]; [largeCircle stroke]; [[UIColor orangeColor] setFill]; [orangeWedge fill]; [orangeWedge stroke]; [[UIColor yellowColor] setFill]; [yellowWedge fill]; [yellowWedge stroke]; [[UIColor greenColor] setFill]; [greenWedge fill]; [greenWedge stroke]; [whiteCircle stroke]; } -(int32_t *) pixelAt:(int) x :(int) y { return &((int32_t *)_imageData)[x + (y * (int) self.frame.size.width)]; } -(void) removeInnerCircle { int32_t invisible = 0; int centerX = self.center.x; int centerY = self.center.y; for (int i = SMALL_RADIUS - 1; i > 0; i--) { float incr = (22.0 / i); for (float j = 0; j <= 360; j += incr) { float angle = RADIANS(j); *[self pixelAt:(sin(angle) * i + centerX) :(cos(angle) * i + centerY)] = invisible; } } } -(void) setUpContext { size_t width = self.frame.size.width; size_t height = self.frame.size.height; _imageData = malloc(4 * width * height); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(_imageData, width, height, 8, width * 4, colorSpace, kCGImageAlphaPremultipliedFirst); CGColorSpaceRelease(colorSpace); CGContextTranslateCTM(context, 0, height); CGContextScaleCTM(context, 1, -1); assert(context != NULL); UIGraphicsPushContext(context); CGContextRelease(context); } -(void) destroyContext { CGImageRef imageRef = CGBitmapContextCreateImage(UIGraphicsGetCurrentContext()); assert(imageRef != NULL); image = [UIImage imageWithCGImage:imageRef]; UIGraphicsPopContext(); free(_imageData); _imageData = NULL; } -(void) awakeFromNib { [self createPaths]; [self setUpContext]; [self drawPaths]; [self removeInnerCircle]; [self destroyContext]; } -(void) drawRect:(CGRect)rect { [image drawInRect:self.frame]; } @end

根据SMALL_RADIUS的值,您可能希望更改-removeInnerCircle的j的增量,以便它不会执行比所需更多的循环。

更改代码以基于当前半径增加j ,所以越靠近中心,需要更改的像素越少!

Took me a bit, but here you go (all bezier paths are instance variables):

EDIT: Made the inner of the circle transparent, but brace yourself, this gets ugly FAST!

#define LARGE_RADIUS 200 #define SMALL_RADIUS 160 #define RADIANS(degrees) ((degrees) / (180.0 / M_PI)) @implementation MyView { UIBezierPath *largeCircle; UIBezierPath *orangeWedge; UIBezierPath *yellowWedge; UIBezierPath *greenWedge; UIBezierPath *whiteCircle; UIImage *image; void *_imageData; } -(void) createPaths { largeCircle = [UIBezierPath bezierPathWithArcCenter:self.center radius:LARGE_RADIUS startAngle:0 endAngle:RADIANS(360) clockwise:YES]; whiteCircle = [UIBezierPath bezierPathWithArcCenter:self.center radius:SMALL_RADIUS startAngle:0 endAngle:RADIANS(360) clockwise:YES]; orangeWedge = [UIBezierPath bezierPath]; [orangeWedge moveToPoint:self.center]; double startAngle = RADIANS(45); double endAngle = RADIANS(135); [orangeWedge addLineToPoint:CGPointMake(sin(startAngle) + self.center.x, cos(startAngle) + self.center.y)]; [orangeWedge addArcWithCenter:self.center radius:LARGE_RADIUS startAngle:startAngle endAngle:endAngle clockwise:YES]; [orangeWedge addLineToPoint:self.center]; startAngle = RADIANS(60); endAngle = RADIANS(120); yellowWedge = [UIBezierPath bezierPath]; [yellowWedge moveToPoint:self.center]; [yellowWedge addLineToPoint:CGPointMake(sin(startAngle) + self.center.x, cos(startAngle) + self.center.y)]; [yellowWedge addArcWithCenter:self.center radius:LARGE_RADIUS startAngle:startAngle endAngle:endAngle clockwise:YES]; [yellowWedge addLineToPoint:self.center]; startAngle = RADIANS(75); endAngle = RADIANS(105); greenWedge = [UIBezierPath bezierPath]; [greenWedge moveToPoint:self.center]; [greenWedge addLineToPoint:CGPointMake(sin(startAngle) + self.center.x, cos(startAngle) + self.center.y)]; [greenWedge addArcWithCenter:self.center radius:LARGE_RADIUS startAngle:startAngle endAngle:endAngle clockwise:YES]; [greenWedge addLineToPoint:self.center]; } -(void) drawPaths { [[UIColor blackColor] setStroke]; [[UIColor redColor] setFill]; [largeCircle fill]; [largeCircle stroke]; [[UIColor orangeColor] setFill]; [orangeWedge fill]; [orangeWedge stroke]; [[UIColor yellowColor] setFill]; [yellowWedge fill]; [yellowWedge stroke]; [[UIColor greenColor] setFill]; [greenWedge fill]; [greenWedge stroke]; [whiteCircle stroke]; } -(int32_t *) pixelAt:(int) x :(int) y { return &((int32_t *)_imageData)[x + (y * (int) self.frame.size.width)]; } -(void) removeInnerCircle { int32_t invisible = 0; int centerX = self.center.x; int centerY = self.center.y; for (int i = SMALL_RADIUS - 1; i > 0; i--) { float incr = (22.0 / i); for (float j = 0; j <= 360; j += incr) { float angle = RADIANS(j); *[self pixelAt:(sin(angle) * i + centerX) :(cos(angle) * i + centerY)] = invisible; } } } -(void) setUpContext { size_t width = self.frame.size.width; size_t height = self.frame.size.height; _imageData = malloc(4 * width * height); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(_imageData, width, height, 8, width * 4, colorSpace, kCGImageAlphaPremultipliedFirst); CGColorSpaceRelease(colorSpace); CGContextTranslateCTM(context, 0, height); CGContextScaleCTM(context, 1, -1); assert(context != NULL); UIGraphicsPushContext(context); CGContextRelease(context); } -(void) destroyContext { CGImageRef imageRef = CGBitmapContextCreateImage(UIGraphicsGetCurrentContext()); assert(imageRef != NULL); image = [UIImage imageWithCGImage:imageRef]; UIGraphicsPopContext(); free(_imageData); _imageData = NULL; } -(void) awakeFromNib { [self createPaths]; [self setUpContext]; [self drawPaths]; [self removeInnerCircle]; [self destroyContext]; } -(void) drawRect:(CGRect)rect { [image drawInRect:self.frame]; } @end

Depending on the value of SMALL_RADIUS, you may wish to change the increment of j in -removeInnerCircle, so that it doesn't perform more loops than necessary.

Changed code to make the increment of j based on the current radius, so the closer to the center you get, the fewer pixels need to be changed!

更多推荐

本文发布于:2023-07-29 18:30:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1318649.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:笔画   形状   Graphics   Core   fill

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!