3次ベジェ曲線を用いた楕円の近似

すぐに忘れてしまいそうなのでメモ.

3次ベジェ曲線と言っても詳細な数式は分からない(し,実際の数式に基づいた描画はアプリケーションがやってくれる)ので,現在の自分に必要なものは3次ベジェ曲線を使って近似楕円を描くための4点の制御点の座標です.なので,ここではこの4点の座標の求め方を考えます(4点で描画できるのは1/4円弧なので,正確には 4*4 点).

3次ベジェ曲線を用いて近似的な円を描くための制御点の座標の求め方は,CGI Error に詳細な記述がありました.この解説では半径 1 の円を考えていますが,もう少し一般化するために半径を r とすると,4 点の座標は以下のように表すことができます.

p1(r, 0), p2(r, a*r), p3(a*r, r), p4(0, r)
ただし,a = 4 * (sqrt(2) - 1) / 3

これを元にして,楕円をベジェ曲線で近似するための 4 点の制御点の座標を求めます.水平方向の半径(長径 or 短径の 1/2)を r, 垂直方向の半径を r' と置き,それぞれの座標の y 座標を r'/r 倍します.

p1'(r, 0), p2'(r, a*r'), p3'(a*r, r'), p4'(0, r')

さらに一般化するために,中心座標を(x, y)として残りも同様に求めていくと,中心(x, y),長径(短径)2*r,短径(長径)2*r' の楕円を3次ベジェ曲線を用いて近似するための制御点 p0 〜 p12の座標は次のようになります.

p0(x+r, y),  p1(x+r, y+a*r'),  p2(x+a*r, y+r'),  p3(x, y+r') ... (0 <= θ <= π/2)
p3(x, y+r'), p4(x-a*r, y+r'),  p5(x-r, y+a*r'),  p6(x-r, y)  ... (π/2 <= θ <= π)
p6(x-r, y),  p7(x-r, y-a*r'),  p8(x-a*r, y-r'),  p9(x, y-r') ... (π <= θ <= 3π/2)
p9(x, y-r'), p10(x+a*r, y-r'), p11(x+r, y-a*r'), p12(x+r, y) ... (3π/2 <= θ <= 2π)