rydotの呟''

プログラミングとかCGとかDTMとか適当にいろいろのことを適度にやる気なく綴るはず。

Bezier曲線の算術演算

Bezier曲線の和と積を求める。

Bernstein多項式

Bernstein多項式はBernstein基底関数の線形結合で表現される多項式の形式である。
Bernstein基底関数は  (x + (1-x))^n を2項定理で展開したものである。
n次Bernstein基底関数  b_{i,n}(x) = {{n}\choose{i}}x^i(1-x)^{n-i}
ここで、 {{n}\choose{i}} は2項係数である。
 {{n}\choose{i}} = {}_n C_i = \frac{n!}{(n-i)!i!}

n次Bernstein多項式  B_n(x) = \sum_{i=0}^n \beta_i b_{i,n}(x)

Bernstein多項式 x=0 \beta_0を、 x=1 \beta_nを通過する。

Bezier曲線

Bezier曲線はBernstein多項式の係数 \beta_iをベクトルとしたものである。

n次のBezier曲線  B_n(x) = \sum_{i=0}^n Q_i b_{i,n}(x)
 Q_i をBezier曲線の制御点という。

ここではBernstein多項式とBezier曲線を同じ物とみなす。

次数上げ

n次多項式では  x^{n+1} の係数を0にして n+1次多項式だと言い張ることができる。
しかし、Bernstein多項式では係数操作が必要となる。
n次の係数を Q_i、n+1次の係数を R_iとして、n次からn+1次にするときの係数操作を示す。

 R_0 = Q_0
 R_{n+1} = Q_n
 R_i = \frac{i}{n+1}Q_{i-1} + (1-\frac{i}{n+1})Q_i, 1 \leq i \leq n

Bezier曲線の和と差

 A(t), B(t), C(t) をそれぞれBezier曲線とする。
係数をそれぞれ Q_i, R_i, S_iとする。
 C(t) = A(t) \pm B(t) となるような C(t)の係数を示す。

AとBの次数が等しい場合

 S_i = Q_i \pm R_i
そのまま。複号は同順である。

AとBの次数が異なる場合

次数の低いBezier曲線を次数上げにより係数操作する。
あとは次数が等しい場合と同様。

Bezier曲線の積

 A(t), B(t), C(t) をそれぞれBezier曲線とする。
次数をそれぞれ  l,m,n とする。
係数をそれぞれ  Q_i, R_j, S_k とする。
 C(t) = A(t) \times B(t) となるような C(t)の係数を示す。
ベクトルの積はいろいろあるが、結合則・分配則を満たすような積であればよい。
よく使う積は普通に使える: 要素ごとの積, スカラー倍, 内積, クロス積

 S_k = \sum_{i,j,i+j=k} Q_i \times R_j \frac{{{l}\choose{i}}{{m}\choose{j}}}{{n}\choose{k}}
 n = l + m

添字が煩雑だが、 Q_i, R_jのすべての組に対して右辺の計算を S_k, k = i + jに蓄積する。