Search code examples
iphoneobjective-cquartz-graphicsgraphicuibezierpath

iPhone iOS Generate star, sunburst or polygon UIBezierPath programmatically


I'm looking for a way to programmatically create stars, sunburst, and other "spiky" effects using UIBezierPath.

Starburst image

UIBezierPath *sunbeamsPath = [UIBezierPath bezierPath];
[sunbeamsPath moveToPoint: CGPointMake(x, y)];

Are there any algorithms that can generate points for sunburst like shapes programmatically, without paths overlapping?

I'm also interested in an irregular shape sunburst like the one below:

irregular sunburst

I would imagine that such algorithm would take a certain number of rays, then roughly divide the circle in a number of segments and generate points for such segment in a clockwise direction. Does an algorithm like the one I'm describing already exists or will I have to write one by myself?

Thank you!


Solution

  • I know this old, but I was curious about the first part of this question myself, and going off jrturton's post, I created a custom UIView that generates a UIBezierPath from center of the view. Even animated it spinning for bonus points. Here is the result:

    enter image description here

    The code I used is here:

    - (void)drawRect:(CGRect)rect {
    CGFloat radius = rect.size.width/2.0f;
    
    [self.fillColor setFill];
    [self.strokeColor setStroke];
    
    UIBezierPath *bezierPath = [UIBezierPath bezierPath];
    CGPoint centerPoint = CGPointMake(rect.origin.x + radius, rect.origin.y + radius);
    
    CGPoint thisPoint = CGPointMake(centerPoint.x + radius, centerPoint.y);
    [bezierPath moveToPoint:centerPoint];
    
    CGFloat thisAngle = 0.0f;
    CGFloat sliceDegrees = 360.0f / self.beams / 2.0f;
    
    for (int i = 0; i < self.beams; i++) {
    
        CGFloat x = radius * cosf(DEGREES_TO_RADIANS(thisAngle + sliceDegrees)) + centerPoint.x;
        CGFloat y = radius * sinf(DEGREES_TO_RADIANS(thisAngle + sliceDegrees)) + centerPoint.y;
        thisPoint = CGPointMake(x, y);
        [bezierPath addLineToPoint:thisPoint];
        thisAngle += sliceDegrees;
    
        CGFloat x2 = radius * cosf(DEGREES_TO_RADIANS(thisAngle + sliceDegrees)) + centerPoint.x;
        CGFloat y2 = radius * sinf(DEGREES_TO_RADIANS(thisAngle + sliceDegrees)) + centerPoint.y;
        thisPoint = CGPointMake(x2, y2);
        [bezierPath addLineToPoint:thisPoint];
        [bezierPath addLineToPoint:centerPoint];
        thisAngle += sliceDegrees;
    
    }
    
    [bezierPath closePath];
    
    bezierPath.lineWidth = 1;
    [bezierPath fill];
    [bezierPath stroke];
    

    }

    And you can download a sample project here:

    https://github.com/meekapps/Sunburst