11
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

UIBezierPath で角の丸い多角形を作る

Posted at

UIBezierPath で角の丸い多角形を作りたくて調べていたら三角形での例を見つけたので、多角形に応用するコードを書いてみました。

以下のコードは UIViewdraw(_:) でこの三角形を描画する例です。UIBezierPath の自作イニシャライザに多角形の頂点を渡しています。

class ShapeView: UIView {
    
    override func draw(_ rect: CGRect) {
        guard let ctx = UIGraphicsGetCurrentContext() else {
            return
        }
        
        // 三角形の頂点座標を作成する
        let radius: CGFloat = 25
        let x: CGFloat = 25, y: CGFloat = 25
        let pos1 = CGPoint(x: x + radius * cos(0), y: y + radius * sin(0))
        let pos2 = CGPoint(x: x + radius * cos(2 / 6 * 2 * .pi), y: y + radius * sin(2 / 6 * 2 * .pi))
        let pos3 = CGPoint(x: x + radius * cos(4 / 6 * 2 * .pi), y: y + radius * sin(4 / 6 * 2 * .pi))

        // UIBezierPathの自作イニシャライザに頂点座標を渡す
        // ratio(0.0~1.0)で丸さを調整できる
        let path = UIBezierPath(roundedPolygon: [pos1, pos2, pos3], ratio: 0.5)
        // パスが閉じていないので、close()で閉じる
        path.close()
        
        ctx.addPath(path.cgPath)
        
        ctx.setLineWidth(4)
        ctx.setStrokeColor(UIColor.red.cgColor)
        ctx.strokePath()
    }

}

UIBezierPath(roundedPolygon:ratio:) の実装です。

extension UIBezierPath {

    public convenience init(roundedPolygon points: [CGPoint], ratio: CGFloat) {
        self.init()

        for i in 0 ..< points.count {
            var prev = i - 1
            if prev < 0 {
                prev = points.count - 1
            }

            var next = i + 1
            if next >= points.count {
                next = 0
            }

            let p1 = points[prev]
            let p2 = points[i]
            let p3 = points[next]

            let p12 = CGPoint(
                x: (p1.x + p2.x) / 2 * ratio + p2.x * (1 - ratio),
                y: (p1.y + p2.y) / 2 * ratio + p2.y * (1 - ratio)
            )
            let p23 = CGPoint(
                x: (p2.x + p3.x) / 2 * ratio + p2.x * (1 - ratio),
                y: (p2.y + p3.y) / 2 * ratio + p2.y * (1 - ratio)
            )

            if self.isEmpty {
                self.move(to: p12)
            } else {
                self.addLine(to: p12)
            }
            self.addQuadCurve(to: p23, controlPoint: p2)
        }
    }

}

ratio の値による角の丸さの変化

参考 URL

11
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?