多項式による曲線の表現: ベジェ曲線

CADなどの分野では、滑らかな曲線または曲面を表現するために、多項式が多く使用される。

コンピュータで使用される文字のフォントも多項式で現れている。

今回の授業では、バーンスタイン多項式(Bernstein polynomial)を紹介して、ベジェ曲線(Bezier curve)の作成方法を学ぶ。

1. バーンスタイン多項式の定義

$n$ 次バーンスタイン基底関数は次のように定義される。

$$ B_{i,n}(x) = {n \choose i} x^{i} (1-x)^{n-i}, \qquad i=0,\ldots,n. $$

ここで ${n \choose i}$ は二項係数として与えられる。

$\{1,x,x^2,\cdots, x^n \}$は$n$次多項式空間(ベクトル空間)の基底となることはよく知られている。 $n$次バーンスタイン基底関数も$n$次の多項式空間の基底となっている。 即ち、任意の$n$次多項式$B(x)$は基底関数$B_{i,n}(x)$の線形結合によって与えられる。

$$ B(x) = \sum_{i=0}^{n} C_{i} b_{i,n}(x) $$

上記の式で書かれている多項式は$n$ 次のバーンスタイン多項式と呼ばれる。 係数 $C_i$ はバーンスタイン係数、またはベジェ係数と呼ばれる。

演習1:バーンスタイン多項式の例

  • 3次バーンスタイン多項式の基底関数のグラフを描画しなさい。
$$ B_{0,3} = (1-x)^3 , \quad B_{1,3} = 3x(1-x)^2, \quad B_{2,3} = 3x^2(1-x) , \quad B_{3,3} = x^3 $$
  • $1^3=(x+(1-x))^3$を展開して、各項と上記の3次バーンスタイン多項式と比較してください。

  • 以下の関数のグラフを描いてください。

$$ f(x)=B_{0,3}(x) + B_{1,3}(x) + B_{2,3}(x)+ B_{3,3}(x) = \sum_{i=0}^{3} B_{i,3}(x) $$$$ g(x)=0\cdot B_{0,3}(x) + \frac{1}{3}B_{1,3}(x) + \frac{2}{3}B_{2,3}(x) + \frac{3}{3} B_{3,3}(x) = \sum_{i=0}^{3}\frac{i}{3} B_{i,3}(x) $$

補足

plot関数を使って、多数のグラフを一括で描画することができる。

plot( x1_list, y1_list, option_1,  x2_list, y2_list, option_2, ... )
In [4]:
x=0:0.01:1;
B0 = (1-x).^3;
B1 = 3 * x .* (1-x).^2;
B2 = 3 * x.^2 .* (1-x);
B3 = x.^3;
plot(x,B0,'-r',x,B1,'-b', x, B2, '-g', x,B3,'-k')
grid on
Gnuplot Produced by GNUPLOT 5.0 patchlevel 3 0 0.2 0.4 0.6 0.8 1 0 0.2 0.4 0.6 0.8 1 gnuplot_plot_1a gnuplot_plot_2a gnuplot_plot_3a gnuplot_plot_4a
In [15]:
# f,gのグラフを描いてください。

一般的な $n$ 次バーンスタイン多項式

以下の式の展開式を確認してください。

$$1^n=(x+(1-x))^n = \sum_{i=0}^n \frac{n!}{i!(n-i)!} x^i(1-x)^{n-i} $$

以下の関数Bernstein(i,n,x)は一般的な$n$次バーンスタイン多項式を表している。特に、階乗の関数はfactorial()である。即ち、

$$ \mbox{factorial}(n) = 1\cdot 2 \cdot 3 \cdots (n-1) \cdot n $$
In [11]:
function value = Bernstein(i,n,x)
  value = factorial(n) / ( factorial(i) * factorial(n-i) ) .* x.^(i) .* (1-x).^(n-i);
end

バーンスタイン多項式の性質

演習2

  • 以下のバーンスタイン多項式の微分を計算して確認しなさい。
$$B'_{0,n}(0)=-n, \quad B'_{1,n}(0)=n, \quad B'_{n-1,n}(1)=-n, \quad B'_{n,n}(1)=n $$
  • すべての$5$次バーンスタイン多項式のグラフを描いてください。
In [44]:
# グラフを描いてください。

2. ベジェ曲線

ベジェ曲線(Bézier Curve)とは、$N$ 個の制御点から得られる N − 1 次曲線である。

$$ f(x) = \sum_{i=0}^{N} C_{i} b_{i,N}(x) $$

ここで、$C_{i}$は制御点またはコントロール点と呼ばれる。

制御点の実際の座標は以下のようになる。

$$ (0, C_0) ,~~ (\frac{1}{N}, ~~ C_1) , ~~ \cdots, ~~ (\frac{i}{N}, C_i) , ~~ \cdots, ~~ (1, C_N) , $$

3次ベジェ曲線の例

3次ベジェ曲線$B(x)$

$$ B(x) = C_0 B_{0,3}(x) + C_1 B_{1,3}(x) + C_2 B_{2,3}(x) + C_3 B_{3,3}(x) $$

の関数値と微分を計算してみます。

$$ B(0) = C_0, \quad B'(0) = 3 (C_1 - C_0), \quad B(1) = C_3, \quad B'(1) = 3(C_3- C_2) $$

演習3

  • 以下の制御点によって決められる3次ベジェ曲線とを制御点が成す折れ線を描きなさい。
$$ C_0 = 0, C_1 = 2, C_2 = -1, C_3 = 0 $$
  • 制御点が成す折れ線の両端の座標と接線の勾配を求めて、3次ベジェ曲線$B(x)$の両端の値と微分と比較してください
In [13]:
C=[0,2,-1,0];
f= 0;
for k=0:3
  f = f+C(k+1)*Bernstein(k,3,x);
end
In [14]:
hold on
plot(0:1/3:1, C, 'r-o')
plot(x,f,'b-')
grid on
Gnuplot Produced by GNUPLOT 5.0 patchlevel 3 -1 -0.5 0 0.5 1 1.5 2 0 0.2 0.4 0.6 0.8 1 gnuplot_plot_1a gnuplot_plot_2a

レポート課題1

ベジェ曲線の制御点を選んで、関数$y=sin(2\pi x)$ ($0\le x \le 1$)の良い近似ベジェ曲線を作成しなさい。

  • ベジェ曲線の次数を自由に選んでください。(最大10次まで)
  • ベジェ曲線の近似が良いがとうかについて、判断の基準を自由に考えてください。
  • 区分的なベジェ曲線を使っても良い。例えば、[0,0.5]と[0.5,1]の区間で二つのベジェ曲線を作ること。
In [19]:
hold on

x=0:0.01:1;  y=sin(2*pi*x); plot(x,y,'b-')

C=[0,3.,-3.,0]; f= 0;
for k=0:3
  f = f+C(k+1)*Bernstein(k,3,x);
end
plot(x,f,'r-')
grid on
Gnuplot Produced by GNUPLOT 5.0 patchlevel 3 -1 -0.5 0 0.5 1 0 0.2 0.4 0.6 0.8 1 gnuplot_plot_1a gnuplot_plot_2a

3. パラメータ曲線で現れるベジェ曲線

実際の応用では、2次元平面上の曲線を自由に表現するために、以下のパラメータ曲線で現れるベジェ曲線が使用される。

$$ F(t) = (X(t), Y(t)) $$

ここで、 $$ X(t) = X_0 B_{0,n}(t) + X_1 B_{1,n}(t) + \cdots + X_n B_{n,n}(t) = \sum_{i=0}^n X_i B_{i,n}(t) $$ $$ Y(t) = Y_0 B_{0,n}(t) + Y_1 B_{1,n}(t) + \cdots + Y_n B_{n,n}(t) = \sum_{i=0}^n Y_i B_{i,n}(t) $$ また、制御点は $$ P_0=(X_0,Y_0), \quad P_1 = (X_1,Y_1),\quad \cdots, \quad P_n=(X_n,Y_n) $$ となる。

ホームページにあるBezier曲線の補足資料(3次ベジェ曲線の例)を参考してください。

2次元平面上のベジェ曲線の例

制御点は以下のようにとる。 $$ P_0 = (0,0), P_1 = (0,1), P_0 = (2,-1), P_3=(3,0) $$

In [65]:
P=[0,0;
   0,1;
   2,-1;
   3,0];
In [70]:
t=0:.001:1;
X=0;Y=0;
for k = 0:3
  X = X + P(k+1,1)*Bernstein(k,3,t);
  Y = Y + P(k+1,2)*Bernstein(k,3,t); 
end
hold on
plot(P(:,1), P(:,2),'r-o')
plot(X,Y,'b-')
grid on
Gnuplot Produced by GNUPLOT 5.0 patchlevel 3 -1 -0.5 0 0.5 1 0 0.5 1 1.5 2 2.5 3 gnuplot_plot_1a gnuplot_plot_2a

レポート課題2

ギリシャの文字$\alpha$をベジェ曲線で書いてください。

In [ ]: