0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ベジェ曲線による円弧の近似

Posted at

はじめに

イラストレータなどでは、円や円弧を描くときにベジェ曲線による近似が行われている。
※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);

image.png

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);

image.png

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);

image.png

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);

image.png

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>

image.png

メモ

見つけたのでメモ。
イラレの曲線で使われているらしい。
フリーハンド曲線のやつかな?まだ読み込めてない。
Siggraph2017で発表。

著者のページに論文データと、発表スライドがある。

論文への直リンク

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?