読者です 読者をやめる 読者になる 読者になる

graphics.hatenablog.com

テクニカルアーティストの技術を書き殴るためのメモ帳

再分割曲面のもうちょい基礎。(2)

ちょっと楽しくなってきたから次は NURBS やってみる。
参考資料はこれ↓と、あと google 先生。


話の流れ

まず パラメトリック曲線 っていうのがあって、それをつかって ベジェ曲線 を定義する。けどただのベジェ曲線だと 円錐曲線 を表現することができないから、それを表現するために 制御点に重み付け をして 有理ベジェ曲線 を定義する。複雑な曲線をこれで表現しようとするとどんどん高次の曲線を使わなきゃいけなくなって、数値計算的な意味での安定性がなくなっちゃう。これを避けるために、複数の有理ベジェ曲線breakpoints(日本語でなんていうかわからない) で繋げて、パラメータの持ち方を変えたのが B-Spline 曲線。で、ベジェのときと同じく円錐曲線を表現するために 有理 B-Spline 曲線 を定義する。これを英語になおすと、Non-Uniform Rational B-Spline、つまり NURBS になる。

まとめると、

パラメトリック曲線
 ↓ [利用]
ベジェ曲線
 ↓ [一般化]
有理ベジェ曲線 
 ↓ [一般化]
B-Spline 曲線
 ↓ [一般化]
有理 B-Spline 曲線 = NURBS 曲線


パラメトリック曲線

曲線を表現するときに、その線上の点をいちいちデータ化してたらものすごく大変。例えば円上の点を1度につき1個ずつデータ化したら点が360個。しかも綺麗な円を描くにはもっと細かく点を打たなきゃいけない。これをパラメータ化して
<br />
\begin{array}{ll}<br />
  y = cos(x) + sin(x),&& 0 \leq x < 2 \pi<br />
\end{array}<br />
にすると、必要なデータは 0 と π/2 の2個だけ、あとは計算して求められる。綺麗な円にしたかったら計算回数を増やせばいい。


ベジェ曲線

制御点 P を使った n 次のベジェ曲線 の数学的な定義はこんなかんじ↓
<br />
\begin{array}{lll}<br />
  C(u) &=& \sum_{i=0}^{n} B_{i,n}(u) P_i,&& 0 \leq u \leq 1 \\<br />
  B_{i,n}(u) &=& \frac{n!}{i!(n-i)!} u^i (1-u)^{n-i} &&<br />
\end{array}<br />
n=3 のベジェ曲線をかいてみるとこうなって↓、赤丸で囲ったのが制御点。
f:id:hal1932:20120808224132j:plain


有理ベジェ曲線

細かい数式の導出はさておき、このベジェ曲線が破綻しないように重み付けをすると、数式はこうなる↓
<br />
\begin{array}{lll}<br />
  C(u) &=& \frac{ \sum_{i=0}^{n} B_{i,n}(u) w_i P_i }{ \sum_{i=0}^{n} B_{i,n}(u) w_i },&& 0 \leq u \leq 1<br />
\end{array}<br />
n=3 の有理ベジェ曲線をかくとこうなって↓、緑丸が制御点。
f:id:hal1932:20120809013352j:plain
これはさっきのベジェ曲線の図をもとに、i=2 の制御点の重みを大きくしたもの。i=2 に相当する部分のイラレの方向線の端点と、i=2 の制御点との距離を矢印でかいてあるんだけど、重みが大きくなるほど、この距離(矢印の長さ)が大きくなる。


B-Spline 曲線

数式の軽い説明は 昨日のエントリ で書いたから省略するけど、B-Spline の定義はこれ↓
<br />
\begin{array}{lll}<br />
  C(u) &=& \sum_{i=0}^n N_{i,n}(u) P_i &&, (u_i \leq u < u_{i+1})<br />
\end{array}<br />
 <br />
  N_{i,0}(u) = \left\{<br />
    \begin{array}{ll}<br />
      1, && 0 \leq u < 1 \\<br />
      0, && otherwise<br />
    \end{array}<br />
  \right<br />
<br />
\begin{array}{lll}<br />
  N_{i,n}(u) &=& \frac{u-u_i}{u_{i+n}-u_i} N_{i,n-1}(u) + \frac{u_{i+n+1}-u}{u_{i+n+1}-u_{i+1}} N_{i+1,n-1}(u)<br />
\end{array}<br />
絵にするとこんなん↓
f:id:hal1932:20120809003126j:plain
イラレでいうところの「アンカーポイント」が breakpoints で、「方向線」の端点が制御点。breakpoints で複数の有理ベジェ曲線がつながってるのがみえると思う。
ここで大事なのが3つ目の数式の、曲線のかたちに影響するのは2つの制御点だけ、ってところ。例えばイラレでベジェかいてるときも、ひとつめの方向線をいくら動かしても、隣のアンカーポイントの位置は変わらずに、そのアンカーポイントに隣接する曲線だけが変化する。アンカーポイントの端点が制御点なわけだから、つまり、制御点をどれだけ動かしても、自分とこの曲線にしか影響しない、制御点の影響が局所的 になってる。そのおかげで、ものすごくデザイン作業がやりやすくなってる。方向線を動かすたびに隣の曲線(次のアンカーポイントの向こうにある曲線)が動いちゃったら、たぶんものすごくやりにくいよね。


有理 B-Spline(NURBS)曲線

で、B-Spline を有理化したのがこれ↓
<br />
\begin{array}{lll}<br />
  C(u) &=& \frac{ \sum_{i=0}^{n} N_{i,p}(u) w_i P_i }{ \sum_{i=0}^{n} N_{i,p}(u) w_i },&& a \leq u \leq b<br />
\end{array}<br />
ロジックは有理ベジェ曲線のときとだいたい同じ。

で、最後。この有理化された P について考える。
 <br />
P_i^w = (x_i, y_i, z_i, w_i) \rightarrow (w_i x_i, w_i y_i, w_i z_i)<br />
B-Spline の最初の式をこれで書き換えるとこうなって↓
<br />
C^w(u) = \sum_{i=0}^n N_{i,p}(u) P_i^w<br />
この曲線(2次元)を曲面(3次元)に拡張すると、こうなる↓
<br />
S^w(u,v) = \sum_{i=0}^n \sum_{j=0}^m N_{i,p}(u) N_{j,q}(v) P_{i,j}^w<br />

おわり!