Skip to content

Instantly share code, notes, and snippets.

@dejager
Created October 18, 2022 05:57
Show Gist options
  • Save dejager/f0822721bea9e19cad91faec91c381b4 to your computer and use it in GitHub Desktop.
Save dejager/f0822721bea9e19cad91faec91c381b4 to your computer and use it in GitHub Desktop.
A SwiftUI Shape that draws a polygon with a given number of corners and a corner radius.
//
// RoundedPolygon.swift
//
// Created by Nate on 2022-10-17.
//
import SwiftUI
struct RoundedPolygon: Shape {
private let radius: CGFloat
private let points: Int
init(cornerRadius: CGFloat, points: Int) {
self.radius = cornerRadius
self.points = points
}
private func calculateCorners(in rect: CGRect,
withRadius radius: CGFloat,
points: Int) -> [CGPoint] {
var corners = [CGPoint]()
let step: CGFloat = (.pi * 2) / CGFloat(points)
let radius: CGFloat = min(rect.midX, rect.midY)
for i in 0 ..< points {
let theta = CGFloat(i) * step
let x = radius + cos(theta) * radius
let y = radius + sin(theta) * radius
corners.append(CGPoint(x: x, y: y))
}
return corners
}
func path(in rect: CGRect) -> Path {
let corners = calculateCorners(in: rect,
withRadius: radius,
points: points)
guard corners.count >= 3 else { return Path() }
var path = Path()
let c1 = corners[0]
let c2 = corners[corners.count - 1]
let startPoint = CGPoint(x: (c1.x + c2.x) / 2,
y: (c1.y + c2.y) / 2)
path.move(to: startPoint)
for n in 0..<corners.count {
let current = corners[n]
let next = n < (corners.count - 1) ? corners[n + 1] : corners[0]
path.addArc(tangent1End: current, tangent2End: next, radius: radius)
}
return path
}
}
@dejager
Copy link
Author

dejager commented Oct 21, 2022

@martinlexow Seems to work alright: https://gist.github.com/dejager/8e292be983cdc39f28560ed24c0a17be. We just need to account for the inset when calculating the point positions. ✌️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment