Skip to content

Instantly share code, notes, and snippets.

@yosshi4486
Created February 17, 2024 08:45
Show Gist options
  • Save yosshi4486/b2b245ef2cd7565f58f6b10ffc3ce5f1 to your computer and use it in GitHub Desktop.
Save yosshi4486/b2b245ef2cd7565f58f6b10ffc3ce5f1 to your computer and use it in GitHub Desktop.
Polygon shape considered a corner radius.
/// 多角形のシェープ.
struct Polygon : Shape {
/// 多角形の頂点の数. デフォルト値は`3`
var numberOfVertex: Int
/// 角の半径. デフォルト値は`3`.
var cornerRadius: CGFloat
/// 直線をトップに配置するかどうかのBool値. デフォルト値は`false`.
///
/// `true`のときはは直線の中心がちょうど上にくる.
/// `false`のときは。多角形の頂点がちょうど上にくる.
var placesLineToTop: Bool
init(_ numberOfVertex: Int = 3, cornerRadius: CGFloat = 3, placesLineToTop: Bool = false) {
precondition(numberOfVertex >= 3)
self.numberOfVertex = numberOfVertex
self.cornerRadius = cornerRadius
self.placesLineToTop = placesLineToTop
}
func path(in rect: CGRect) -> Path {
var path = Path()
let center = CGPoint(x: rect.midX, y: rect.midY)
let radius = rect.size.width / 2
let step = Double.pi * 2 / Double(self.numberOfVertex)
let initialAngle = -(.pi / 2) + step / 2 * CGFloat(placesLineToTop ? 1 : 0)
let points: [CGPoint] = (0..<self.numberOfVertex).map({ cornerNumber in
let angle = initialAngle + step * CGFloat(cornerNumber)
let x = center.x + cos(angle) * radius
let y = center.y + sin(angle) * radius
return CGPoint(x: x, y: y)
})
for i in (0..<points.count) {
let nextPoint = i < points.count - 1 ? points[i + 1] : points[0]
path.addArc(tangent1End: points[i], tangent2End: nextPoint, radius: cornerRadius)
}
path.closeSubpath()
return path
}
}
#Preview {
Polygon(5, cornerRadius: 3, placesLineToTop: true)
.stroke(lineWidth: 2)
.frame(width: 25, height: 25)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment