Created
October 18, 2022 05:57
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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 | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@martinlexow Seems to work alright: https://gist.github.com/dejager/8e292be983cdc39f28560ed24c0a17be. We just need to account for the inset when calculating the point positions. ✌️