-
Notifications
You must be signed in to change notification settings - Fork 33
/
NSBezierPath+ULIRegularPolygon.m
54 lines (41 loc) · 1.8 KB
/
NSBezierPath+ULIRegularPolygon.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//
// NSBezierPath+ULIRegularPolygon.m
// Stacksmith
//
// Created by Uli Kusterer on 30.04.11.
// Copyright 2011 Uli Kusterer. All rights reserved.
//
#import "NSBezierPath+ULIRegularPolygon.h"
@implementation NSBezierPath (ULIRegularPolygon)
-(void) appendRegularPolygonAroundPoint: (NSPoint)centre startPoint: (NSPoint)startCorner cornerCount: (NSInteger)numCorners
{
NSAssert( (numCorners >= 3), @"Too few corners on polygon." );
// To draw a regular polygon, you simply calculate as many evenly-spaced
// points on a circle as you need corners, then connect them with lines.
CGFloat xDiff = fabs(startCorner.x -centre.x);
CGFloat yDiff = fabs(startCorner.y -centre.y);
CGFloat radius = sqrt( xDiff * xDiff + yDiff * yDiff ); // Pythagoras xDiff^2 + yDiff^2 = distance as the bird flies.
if( xDiff <= 0 ) // Don't divide by zero, don't do work if there's nothing to draw.
return;
CGFloat degrees = (xDiff == 0) ? 0 : ((yDiff == 0) ? 0.5 * M_PI : yDiff / xDiff); // Calc angle at which centre & startCorner are, so we know at what angle to put the first point.
CGFloat stepSize = (2.0 * M_PI) / ((CGFloat)numCorners);
// Draw first corner at start angle:
NSPoint firstCorner = NSZeroPoint;
firstCorner.x = centre.x +radius * cos( degrees );
firstCorner.y = centre.y +radius * sin( degrees );
[self moveToPoint: firstCorner];
// Now draw following corners:
for( NSInteger x = 0; x < numCorners; x++ )
{
NSPoint currCorner = NSZeroPoint;
degrees += stepSize;
if( degrees > (2.0 * M_PI) )
degrees -= (2.0 * M_PI);
currCorner.x = centre.x +radius * cos( degrees );
currCorner.y = centre.y +radius * sin( degrees );
[self lineToPoint: currCorner]; // Draw edge from prev to curr corner.
}
// Now close the shape by drawing final edge:
[self lineToPoint: firstCorner];
}
@end