CAD(Computer Aided Design)の分野など、コンピュータ上で滑らかな曲線や曲面を表現するために、多項式がよく使用されます。文字のフォントも、その一例です。
今回と次回の授業では、そのような多項式によって表される曲線の一つであるベジェ曲線(Bezier curve)に焦点を当てます。
特に、今回の授業では準備として、ベジェ曲線の基になる多項式について説明します。
非負整数 $n$ に対して、次の式で定義される $(n+1)$ 個の関数を $n$ 次バーンスタイン基底関数(Bernstein basis function)と呼びます。
$$ B_{i,n}:\mathbb{R}\to\mathbb{R}, \quad B_{i,n}(x)={}_n C_i x^i (1-x)^{n-i}, \quad i=0,\ldots,n $$ここで、${}_n C_i$ は二項係数($n$ 個から $i$ 個選ぶ組合せの総数)であり、階乗を用いれば
$$ {}_n C_i=\frac{n!}{i!(n-i)!} $$と表されます。
具体的に書いてみると、$0$ 次バーンスタイン基底関数は
$$ B_{0,0}(x)=1, $$$1$ 次バーンスタイン基底関数は
$$ B_{0,1}(x)=1-x, \quad B_{1,1}(x)=x, $$$2$ 次バーンスタイン基底関数は
$$ B_{0,2}(x)=(1-x)^2, \quad B_{1,2}(x)=2x(1-x), \quad B_{2,2}(x)=x^2 $$となります。
$n$ 次以下の多項式からなるベクトル空間を考えるとき、$\left\{1,x,x^2,\ldots,x^n\right\}$ が基底になることは容易に分かりますが、$(n+1)$ 個の $n$ 次バーンスタイン基底関数もまた基底になります。このことから、任意の $n$ 次以下の多項式は線形結合
$$ \sum_{i=0}^n r_i B_{i,n}(x) $$の形で書けることが分かります。
このような形で表された多項式を、$n$ 次バーンスタイン多項式(Bernstein polynomial)と呼びます。
例として、$n=3$ の場合について考えます。
$3$ 次バーンスタイン基底関数は
$$ B_{0,3}(x)=(1-x)^3, \quad B_{1,3}(x)=3x(1-x)^2, \quad B_{2,3}(x)=3x^2(1-x), \quad B_{3,3}(x)=x^3 $$であり、$0\leq x\leq 1$ の範囲でこれらのグラフを描画すると次のようになります。
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0,1,101) #0から1まで101個の数からなる1次元配列
B = [(1-x)**3,3*x*(1-x)**2,3*x**2*(1-x),x**3] #各バーンスタイン基底関数の値(1次元配列)からなるリスト
for i in range(4): #i=0から3
plt.plot(x,B[i],label="$B_{"+str(i)+",3}(x)$") #labelの指定は少し複雑、strは文字列に変換する関数
plt.grid()
plt.legend()
plt.show()
さらに、
$$ r_0=1,\quad r_1=2,\quad r_2=3,\quad r_3=1 $$に対して $3$ 次バーンスタイン多項式
$$ \sum_{i=0}^3 r_i B_{i,3}(x) $$を考えるとき、$0\leq x\leq 1$ におけるグラフは次のようになります。
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0,1,101)
B = [(1-x)**3,3*x*(1-x)**2,3*x**2*(1-x),x**3]
r = [1,2,3,1] #バーンスタイン多項式の係数のリスト
y = 0
for i in range(4):
y = y+r[i]*B[i]
plt.plot(x,y,label="$1,2,3,1$")
plt.grid()
plt.legend()
plt.show()
$4$ 次バーンスタイン基底関数の $0\leq x\leq 1$ におけるグラフを描画してください。ただし、五つのグラフを一つの図に描画すること。
#演習1のコード
$4$ 次バーンスタイン多項式
$$ \sum_{i=0}^4 r_i B_{i,4}(x) $$を
$$ r_0=1,\quad r_1=1,\quad r_2=1,\quad r_3=1,\quad r_4=1 $$と
$$ r_0=0,\quad r_1=\frac{1}{4},\quad r_2=\frac{1}{2},\quad r_3=\frac{3}{4},\quad r_4=1 $$に対してそれぞれ考えるとき、$0\leq x\leq 1$ におけるグラフを描画してください。ただし、二つのグラフを一つの図に描画すること。
さらに、一つ目のグラフについて、得られた結果の理由を考察してください。
#演習2のコード
バーンスタイン多項式は、関数の近似に用いることができます。
$0\leq x\leq 1$ における連続関数 $f(x)$ が与えられたとき、
$$ r_i=f\left(\frac{i}{n}\right),\quad i=0,\ldots,n $$に対して $n$ 次バーンスタイン多項式
$$ \sum_{i=0}^n r_i B_{i,n}(x) $$を考えると、これは $n$ が大きいほどに $0\leq x\leq 1$ における $f(x)$ の良い近似になります。
(より厳密に言うと、$n\to\infty$ のときに $0\leq x\leq 1$ において $f(x)$ に一様収束します。)
$n$ 次バーンスタイン基底関数の値を返す関数Bernstein(i,n,x)
を定義した上で、関数
を $20$ 次バーンスタイン多項式によって近似し、元の関数と得られた多項式の $0\leq x\leq 1$ におけるグラフを描画してください。ただし、二つのグラフを一つの図に描画すること。
#演習3のコード
#階乗の計算は、mathライブラリのfactorial関数を使うとよい
演習1~演習3に取り組んでください。