音楽アプリの再生/停止ボタンによくある、おにぎりのような右向きの角が丸い三角形を書くSwiftプログラムです。
この関数はUIBezierPathを返します。
関数の引数は x y radius ratio angleの5つです。それぞれの意味は図の通りです。angleは後から追加したので図に載っていませんが、全体を時計周り方向に回転させるパラメータです。
パスの作成に使用しているメソッドは
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が0.0のときは、始点と終点が頂点になります。このとき太い線で輪郭を描くと、lineCapStyleによっては端がぎざぎざになります。