LoginSignup
65
63

More than 3 years have passed since last update.

おにぎりのような右向きの角が丸い三角形

Last updated at Posted at 2016-10-30

音楽アプリの再生/停止ボタンによくある、おにぎりのような右向きの角が丸い三角形を書くSwiftプログラムです。

この関数はUIBezierPathを返します。
関数の引数は x y radius ratio angleの5つです。それぞれの意味は図の通りです。angleは後から追加したので図に載っていませんが、全体を時計周り方向に回転させるパラメータです。
softTriangle.png

パスの作成に使用しているメソッドは

open func addQuadCurve(to endPoint: CGPoint, controlPoint: CGPoint)

です。

引数をCGFloatにするかDoubleにするかは迷うところでありました。使用する際、都合が悪ければ変更してください。

func roundTriangle(x: Double, y: Double, radius: Double, ratio: Double, angle: Double) -> UIBezierPath {

    var ratio = CGFloat(ratio)
    if ratio < 0.0 {
        ratio = 0.0
    } else if 1.0 < ratio {
        ratio = 1.0
    }

    let pos1 = CGPoint(x: x + radius * cos(0.0 + angle), y: y + radius * sin(0.0 + angle))
    let pos2 = CGPoint(x: x + radius * cos(2.0 / 3.0 * M_PI + angle), y: y + radius * sin(2.0 / 3.0 * M_PI + angle))    
    let pos3 = CGPoint(x: x + radius * cos(4.0 / 3.0 * M_PI + angle), y: y + radius * sin(4.0 / 3.0 * M_PI + angle))    

    let ratio2 = 1.0 - ratio
    let pos1f = CGPoint(x: (pos1.x + pos2.x) / 2.0 * ratio + pos1.x * ratio2,
                        y: (pos1.y + pos2.y) / 2.0 * ratio + pos1.y * ratio2)
    let pos2b = CGPoint(x: (pos1.x + pos2.x) / 2.0 * ratio + pos2.x * ratio2,
                        y: (pos1.y + pos2.y) / 2.0 * ratio + pos2.y * ratio2)
    let pos2f = CGPoint(x: (pos2.x + pos3.x) / 2.0 * ratio + pos2.x * ratio2,
                        y: (pos2.y + pos3.y) / 2.0 * ratio + pos2.y * ratio2)
    let pos3b = CGPoint(x: (pos2.x + pos3.x) / 2.0 * ratio + pos3.x * ratio2,
                        y: (pos2.y + pos3.y) / 2.0 * ratio + pos3.y * ratio2)
    let pos3f = CGPoint(x: (pos3.x + pos1.x) / 2.0 * ratio + pos3.x * ratio2,
                        y: (pos3.y + pos1.y) / 2.0 * ratio + pos3.y * ratio2)
    let pos1b = CGPoint(x: (pos3.x + pos1.x) / 2.0 * ratio + pos1.x * ratio2,
                        y: (pos3.y + pos1.y) / 2.0 * ratio + pos1.y * ratio2)

    let roundTrianglePath = UIBezierPath()

    roundTrianglePath.move(to: pos1f)
    roundTrianglePath.addLine(to: pos2b)
    roundTrianglePath.addQuadCurve(to: pos2f, controlPoint: pos2)
    roundTrianglePath.addLine(to: pos3b)
    roundTrianglePath.addQuadCurve(to: pos3f, controlPoint: pos3)
    roundTrianglePath.addLine(to: pos1b)
    roundTrianglePath.addQuadCurve(to: pos1f, controlPoint: pos1)

    return roundTrianglePath
}

ratioを変化させるとこのようになります。
ratio.png

angleを変化させるとこのようになります。
angle.png

また、ratioが0.0のときは、始点と終点が頂点になります。このとき太い線で輪郭を描くと、lineCapStyleによっては端がぎざぎざになります。

65
63
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
65
63