Edited at

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

More than 1 year has passed since last update.

音楽アプリの再生/停止ボタンによくある、おにぎりのような右向きの角が丸い三角形を書く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によっては端がぎざぎざになります。