Created
February 17, 2024 08:45
-
-
Save yosshi4486/b2b245ef2cd7565f58f6b10ffc3ce5f1 to your computer and use it in GitHub Desktop.
Polygon shape considered a corner radius.
This file contains hidden or 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
/// 多角形のシェープ. | |
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