Skip to content

Instantly share code, notes, and snippets.

@jonasreinsch
Created December 2, 2014 11:39
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save jonasreinsch/57d648769d790289d2ce to your computer and use it in GitHub Desktop.
Save jonasreinsch/57d648769d790289d2ce to your computer and use it in GitHub Desktop.
function to create a UIBezierPath for a (rounded corner) polygon in Swift
// this is a port from the following Objective C code
// http://stackoverflow.com/a/24770675/1269132
func roundedPolygonPath(
#square:CGRect,
#lineWidth:Double,
#sides:NSInteger,
#cornerRadius:Double) -> UIBezierPath {
let path = UIBezierPath()
// how much to turn at every corner
let theta = 2.0 * M_PI / Double(sides)
// offset from which to start rounding corners
let offset = cornerRadius * tan(theta / 2.0)
let squareWidth = min(Double(square.size.width), Double(square.size.height))
// calculate the length of the sides of the polygon
var length = squareWidth - lineWidth
// if not dealing with polygon which will be square with all sides...
if sides % 4 != 0 {
// ... offset it inside a circle inside the square
length = length * cos(theta / 2.0) + offset/2.0
}
let sideLength = length * tan(theta / 2.0)
// start drawing at `point` in lower right corner
var point = CGPointMake(CGFloat(squareWidth / 2.0 + sideLength / 2.0 - offset),
CGFloat(squareWidth - (squareWidth - length) / 2.0))
var angle = M_PI
path.moveToPoint(point)
// draw the sides and rounded corners of the polygon
for var side = 0; side < sides; side++ {
point = CGPointMake(CGFloat(Double(point.x) + (sideLength - offset * 2.0) * cos(angle)),
CGFloat(Double(point.y) + (sideLength - offset * 2.0) * sin(angle)))
path.addLineToPoint(point)
let center = CGPointMake(CGFloat(Double(point.x) + cornerRadius * cos(angle + M_PI_2)),
CGFloat(Double(point.y) + cornerRadius * sin(angle + M_PI_2)))
path.addArcWithCenter(center, radius: CGFloat(cornerRadius), startAngle: CGFloat(angle - M_PI_2), endAngle: CGFloat(angle + theta - M_PI_2), clockwise: true)
point = path.currentPoint // we don't have to calculate where the arc ended ... UIBezierPath did that for us
angle += theta
}
path.closePath()
return path
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment