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

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

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

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

1. バーンスタイン多項式

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

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

ここで ${n \choose i}$ は二項係数 $_nC_i$ を意味します。

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

$$ y(x) = \sum_{i=0}^{n} C_{i} B_{i,n}(x) $$

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

例1:バーンスタイン基底関数

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

バーンスタイン多項式による曲線の表示

バーンスタイン基底関数を用いて、基底の線形結合で得られる曲線を描いてみます。

多項式の例:

$$ y(x)= 1\cdot B_{0,3}(x) + 2\cdot B_{1,3}(x) + 3\cdot B_{2,3}(x)+ 1\cdot B_{3,3}(x) $$

特殊な多項式: 定数1をとる関数

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

特殊な多項式: $y=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, ... )

一般的な $n$ 次バーンスタイン基底関数

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

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

$n$ 次バーンスタイン基底関数の微分は以下の性質を持っています。

$x=0$ のとき、

$$ B'_{0,n}(0)=-n, \quad B'_{1,n}(0)=n, \quad B'_{2,n}(0)=\cdots = B'_{n,n}(0)=0 $$

$x=1$ のとき、

$$ B'_{0,n}(1)=\cdots = B'_{n-2,n}(1)=0 , \quad B'_{n-1,n}(1)=-n, \quad B'_{n,n}(1)=n $$

以下の関数Bernstein(i,n,x)は、一般的な $n$ 次バーンスタイン基底関数を定義しています。ここで、階乗の関数はfactorial()です。即ち、

$$ \mbox{factorial}(n) = 1\cdot 2 \cdot 3 \cdots (n-1) \cdot n $$

バーンスタイン基底関数の性質

演習1

2. ベジェ曲線

ベジェ曲線(Bézier curve)は、バーンスタイン基底関数の線形結合で表される曲線です。

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

係数 $C_i$ に対して、点 $P_i({i}/{N}, C_{i})$ は制御点またはコントロール点と呼ばれます。

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

3次ベジェ曲線の例

3次ベジェ曲線

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

演習2

$$ C_0 = 0,\ \ C_1 = 2,\ \ C_2 = -1,\ \ C_3 = 0 $$

考察

レポート課題

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

3. ファイルへの書き込み・ファイルからの読み込み

Pythonにおいてデータをファイルへ書き込んだり、データをファイルから読み込んだりする方法はいくつかありますが、Numpyを用いるとNumpyの配列をそのままテキストファイルに書き込んで、後で読み込むことが簡単にできます。

以下のコードでは、ベジェ係数(1次元配列)をテキストファイルに書き込んで保存した後、そのテキストファイルから読み込んだ係数に対応するベジェ曲線を描いています。