はじめに
イラストレータなどでは、円や円弧を描くときにベジェ曲線による近似が行われている。
※CADなどでは、NURBSによる正確な円や円弧が使われる。
Processing標準の円弧描画命令を使っても描けるのだが、タートルグラフィックスのように使いたかったので、やってみた次第です。
環境
Processing 4
ベジェ曲線による円弧近似の一般公式
ベジェ曲線の制御点を
P_0, P_1, P_2, P_3
とし、
P_0を始点、P_3を終点
とするとき、
P_1=P_0+\alpha t_0
P_2=P_3-\alpha t_1
t_0,t_1は、それぞれ始点・終点での円弧の接線方向を正規化したベクトルで、
t_0=(0,1)
は、明らか。
例えば、45度のとき
t_1=(-\frac{\sqrt2}{2},\frac{\sqrt2}{2})
となる。αは
\alpha=\frac{4}{3}\tan(\frac{\theta}{4})
で、定義され、
例えば、45度のとき
\alpha=\frac{4}{3}\tan(\frac{\pi}{16})
となる。
この公式は、60度以下なら非常に精度が高く、90度でも実用的な精度がある。
90度を超えると、使い物にならない。
90度の円弧
\alpha=\frac{4}{3}\tan(\frac{\theta}{4})=\frac{4}{3}\tan(\frac{\pi}{8})\approx 0.55228474983
P_1=P_0+\alpha t_0=(1,0.55228474983)
P_2=P_3-\alpha t_1=(0.55228474983,1)
size(110,110);
noFill();
scale(100);
strokeWeight(0.01);
bezier(1, 0,
1, 0.5523,
0.5523, 1,
0, 1);
stroke(255,0,0);
circle(0,0,2);
60度の円弧
\alpha=\frac{4}{3}\tan(\frac{\theta}{4})=\frac{4}{3}\tan(\frac{\pi}{12})\approx 0.3572655899
P_1=P_0+\alpha t_0=(1,0.3572655899)
P_2=P_3-\alpha t_1=(0.5,\frac{\sqrt3}{2})-\alpha(-\frac{\sqrt3}{2},0.5)
=(0.80940107675, 0.68739260883)
size(110,110);
noFill();
scale(100);
strokeWeight(0.01);
bezier(1, 0,
1, 0.3573,
0.8094, 0.6874,
0.5, 0.866);
stroke(255,0,0);
circle(0,0,2);
45度の円弧
\alpha=\frac{4}{3}\tan(\frac{\theta}{4})=\frac{4}{3}\tan(\frac{\pi}{16})\approx 0.26521648984
P_1=P_0+\alpha t_0=(1,0.26521648984)
P_2=P_3-\alpha t_1=(\frac{\sqrt2}{2},\frac{\sqrt2}{2})-\alpha(-\frac{\sqrt2}{2},\frac{\sqrt2}{2})
=(0.89464315963,0.51957040273)
size(110,110);
noFill();
scale(100);
strokeWeight(0.01);
bezier(1, 0,
1, 0.2652,
0.8946, 0.5196,
0.7071, 0.7071);
stroke(255,0,0);
circle(0,0,2);
30度の円弧
\alpha=\frac{4}{3}\tan(\frac{\theta}{4})=\frac{4}{3}\tan(\frac{\pi}{24})\approx 0.17553666345
P_1=P_0+\alpha t_0=(1,0.17553666345)
P_2=P_3-\alpha t_1=(\frac{\sqrt3}{2}, 0.5)-\alpha(-0.5, \frac{\sqrt3}{2})
=(0.9537937355, 0.34798079015)
size(110,110);
noFill();
scale(100);
strokeWeight(0.01);
bezier(1, 0,
1, 0.1755,
0.9538, 0.3480,
0.8660, 0.5);
stroke(255,0,0);
circle(0,0,2);
SVGによる90度円弧の誤差比較
SVGフォーマットでテキストエディタでベタ書き。
100mm四方の領域を用意。(単位をミリにする)
1行目:赤:ベジェ曲線による近似円弧
2行目:緑:ベジェハンドルを半径*0.5で代用
3行目:青:円命令
4行目:黃:円弧命令
<svg width="100mm" height="100mm" viewBox="0 0 100 100">
<path d="M 0,5 C 0,2.238575 2.238575,0 5,0" fill="none" stroke-width="0.02" stroke="red" />
<path d="M 0,5 C 0,2.5 2.5,0 5,0" fill="none" stroke-width="0.02" stroke="lime" />
<circle r="5" cx="5" cy="5" fill="none" stroke-width="0.02" stroke="blue" />
<path d="M 0,5 A 5,5 0 0 1 5,0" fill="none" stroke-width="0.02" stroke="yellow" />
</svg>
メモ
見つけたのでメモ。
イラレの曲線で使われているらしい。
フリーハンド曲線のやつかな?まだ読み込めてない。
Siggraph2017で発表。
著者のページに論文データと、発表スライドがある。
論文への直リンク