SSブログ

Bezier曲線による関数の近似 - その6 [レンズ形状をBezierで描く]

Bezier曲線を関数近似に使いたいという話の続き。前回で誤差の振る舞いがなんとなくわかった。そんなもん、普通に使っているBezier曲線は3次の多項式の媒介変数による曲線の表現なので、わざわざ計算しなくてもわかるじゃん、というのはその通りだけど。

ということで、今回は3次元空間内のBezier曲面の話。これまで僕にとって、とりあえずネットを見る限りでは、Bezier曲面の定義は教えてくれるけどどう使うのかよくわからなくて、そんなのもあるんだ、ぐらいの認識だった....

11  Bezier曲面

2次元平面上の曲線を描くためのBezier曲線は簡単に3次元空間の曲線に拡張できる。それは単に制御点$\boldsymbol{P}_i$を3次元の点だとみなせばいい。 \begin{align} \boldsymbol{B}(t) &= \sum_i \boldsymbol{P}_i b_{n-1,i}(t) \nonumber \\ &= \sum_i (x_i,y_i,z_i) b_{n-1,i}(t) \end{align} これは簡単。これで3次元空間内を滑らかにどの向きにでも描くことができる。これは2次元でのイメージがあるのでなんとなくわかる。

さらに3次元空間ではBezier曲面が定義できる。曲線ではパラメータが$t$のひとつだけだったのを$(u,v)$のふたつにすればいい。 \begin{equation} \boldsymbol{B}(u,v) = \sum_{i,j} \boldsymbol{P}_{i,j} b_{n-1,i}(u)b_{n-1,j}(v) \label{bezierfurface} \end{equation} 制御点はふたつの添字$(i,j)$を持っていて、凸包が0でない有限の体積を持てば$\boldsymbol{B}(u,v)$は面を張る。曲線(パラメータがひとつ)の場合でも自己交差のある曲線が描けたように、面でも自己交差のある複雑な面を描くこともできる。

しかし、面の場合自己交差があると扱いがめんどくさくなるので、あまり役には立たない。もともとBezierさんCasteljauさんたちは車のボディなんかの自由な曲面を少ないパラメータで表現する方法を考えていてたどり着いたそうなので、複雑で難しそうな2次元平面の曲線よりは素直な3次元の曲面が先にあったんだろう。

式-\ref{bezierfurface}は曲線の自然な拡張で、片方のパラメータ$u$のBezier曲線群をもう一方の$v$の曲線で補間した(あるいはその逆)と見なすことができる。ところが曲面になるとなんだかずいぶん難しい。そもそも自由な曲面を頭の中に描くというのが難しい。

さらにBezier曲線の場合、曲線の始点と終点が制御点の位置と一致する。3次Bezier曲線の場合4つの制御点があって、曲線の上にない制御点はふたつだけになっている。ところが式-\ref{bezierfurface}では面と一致する点は4つしかない。3次の場合残りの12点($=4\times 4 -4$)はどうやって決めるか、というとぱっと思い浮かばない。

Bezierさんたちがどういうふうに曲面を使っていたのかよく知らないんだけど、車のボディとかだとひとつは空力的な要請と、あとはデザイナの、こう言う面がかっこいいとかいう感覚的な要求を按分することになるんだろう。

空力的な要請も、空気抵抗最小の形状を数値積分で決める、というよりは(少なくとも考え出された60年ほど前当時は)風洞でモデルのあっち削りこっち足したりした結果を落とし込むというかっこうだったに違いない。

つまり何かの近似曲面として数学的に決定されるよりかは、CADの上で「こんな形に」「こんなもんかな」「いんじゃね」みたいにして決まることの方が多かったんではないか、と思える。今の使われ方も主にはそういうのだろうし。

したがって、曲線はともかく、曲面を3次元空間の関数近似に使うというのは本来の目的から外れているんだろう。

しかしあえてやりたい。まあ、いいじゃん。

11.1  8分の1球

まず、難しいので一般的なところから始めるのではなくて、ケーススタディからやろう。

こないだ2次元で4分の1円を描いた。同じように8分の1球を描いてみよう。

中心を原点に移した制御点 \begin{equation} \begin{array}{rccr} p_0 = (& 0 & 1 & ) \\ p_1 = (& (\sqrt{7}-1)/3 & 1& ) \\ p_2 = (& 1 & (\sqrt{7}-1)/3 & )\\ p_3 = (& 1 & 0 & )\\ \end{array} \end{equation} を3次元の$x$-$y$平面と$x$-$z$平面に配置して考える。
0208quarterhalfsphere.png
$x$-$y$平面と$x$-$z$平面のそれぞれの制御点の直積の位置に新しい制御点を追加すればよさそうだということは思いつく。つまり一番底の$x$-$y$平面の4点、図中緑矢印の0のレベルははそのまま緑矢印1の$z=(\sqrt{7}-1)/3$の高さにコピーして、さらに緑矢印2に対応する位置にこの長さの比(Affine不変なので)で小さくしてコピーする。そして$z=1$の位置は4点が一致するように配置するといけそうな気がする。

実際にそれにしたがって制御点を追加して、Bezier曲面の関数をMathematicaでプロットしたのが
0208shperetest.png
もっともらしく見える。球だと半径は1なので、面の各点から原点への距離の1との差をふたつのパラメータに対してプロットするとこの下の図みたいな感じになる。
0208shpereerror.png
図の$v=0$の線上でずっと0なのはちょうど$z=1$の点に対応しているせい。2次元の4分の1円では最大誤差が約0.2%ぐらいだったので少し増えているが、倍まではなさそうなのは、直交する方向の誤差最大の位置がズレてる、ということだろうけど厳密にはよくわからない。

しかし、このやりかたで3次元の面のための制御点が作れることは正しそうである。

せっかくたどり着いたので制御点の座標を全部あげておく。 \begin{align} &\begin{array}{cccc} (0,0,1) & (a,0,1) & (1,0,a) & (1,0,0) \\ (0,0,1) & (a,a^2,1) & (1,a,a) & (1,a,0) \\ (0,0,1) & (a^2,a,1) & (a,1,a) & (a,1,0) \\ (0,0,1) & (0,a,1) & (0,1,a) & (0,1,0) \end{array} \\ a &= \frac{\sqrt{7}-1}{3} \end{align} 見やすいように$z=1$の頂点からに並び替えた。

なんてぐあいに、8分の1球ではヒューリスティックに制御点を探してたまたまうまくいった。でも一般の場合はどうすればいいんだろう。

曲線の場合と同じように端点からの微分の値を一致させることを考えることにして、次に続く。
nice!(0)  コメント(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。