goo blog サービス終了のお知らせ 

gooブログはじめました!

写真付きで日記や趣味を書くならgooブログ

スプライン曲線でだるまを描く

2019-09-29 08:24:23 | ブログ
 8月18日付のブログで記載したように、3DCGに入門したので、スプライン曲面の技法を使って「だるま」のようなオブジェクトの3DCGモデルを作ってみたくなった。

 そのための準備として、まず(x,y)平面上に点列Q0,Q1,...,Qnが与えられたときに、この点列を通過するスプライン曲線を求めることによってスプライン補間をする技法を学ぶことにした。

 (x,y)平面上にデータ(Xi,Yj)が与えられたときに、このデータをスプラインで補間する技法については、2019年1月27日付ブログ「スプライン曲線は面白い」で記載している。この技法は、x軸方向に単調な曲線しか表現できないので、x軸に対して単調でない曲線も表現できるようにより自由度の大きいスプライン技法の習得に挑戦することにした。

 具体的には、パラメータtを使って
   x=(t),y=g(t),0=<t=<T
とおくことによって曲線を表現する。この方法は、曲線のパラメトリック表現とよばれる。

 q次のBスプライン関数は、パラメータtの関数であり、ここではNq(t)と表記することにする。

 例えば、3次のBスプライン関数N3(t)は、-2<t<2の区間に存在し、次の4つの3次曲線を連結したものである。
   0=<t=<1:(3t^3-6t^2+4)/6
   -1=<t=<0:(-3t^3-6t^2+4)/6
   1=<t=<2:-(t-2)^3/6
   -2=<t=<1:(t+2)^3/6
   2=<tおよび-2=>t:0

 関数N3(t)は、t=-1,t=0およびt=1において間数値と一次微分係数が連続な曲線になることが確かめられる。

 N3(t-j)は、t=jのときN3(0)となる関数である。N3(t-(j-1))は、N3(t-j)を左方向に1だけシフトした関数、N3(t-(j+1))は、N3(t-j)を右方向に1だけシフトした関数である。

 (x,y)平面上に与えられた任意の点列Q0,Q1,...,Qnの各々に対応する制御点の点列P0,P1,...,Pnを考える。Qi,Piは、原点Oからの位置ベクトルとみなしてよい。

 N3(t-j)を係数とするベクトルPjの次の線形結合をP(t)とおくと、
   P(t)=N3(t+2)P-2+N3(t+1)P-1+N3(t-0)P0+N3(t-1)P1+...+N3(t-j)Pj+...+N3(t-n)Pn+N3(t-(n+1))Pn+1+N(t-(n+2))Pn+2  (1)
は、P0,P1,...,Pnを制御点とする3次のBスプライン曲線を表す。ただし、P-2=P-1=P0,Pn=Pn+1=Pn+2とする。

 i=0,1,...,nを各々i=n,n-1,...,0に変更してもP(t)が不変でなければならないので、P(t)の左端の項とP(t)の右端の項は対称となる。

 例えばj=<t=<j+1の範囲の任意のtについて、ゼロでない係数N3(t-(j-1)),N3(t-j),N3(t-(j+1))およびN3(t-(j+2))を重ね合わせた(加算した)ものは1になる。特にt=jのとき、N3(t-(j+2))は0であるので、前の3つの係数を加えたものが1になる。

 一般には、曲線P(t):(0=<t=<n)のすべての係数を加えたものが1になる。ベクトルの線形結合は、係数の和が1のとき、アフィン結合とよばれる。位置ベクトルの一般の線形結合は、原点の選び方に依存する。しかし、アフィン結合は原点の選び方に依存しない。曲線P(t)は、アフィン結合であるから、その回転や平行移動ばかりでなく、拡大縮小などの変形も容易に行える。言い換えれば、曲線の操作をしやすい表現形式になっているということである。

 そうは言っても、与えられた点列Q0,Q1,...,Qnに対して制御点の点列P0,P1,...,Pnがどのような意味をもつのか理解するのはかなり難しい。簡単に言えば、与えられた点列を通過する曲線として曲線P(t)を用いればよいということになる。

 そこで、点列Q0,Q1,...,Qnが曲線P(t)を通過するような制御点の点列P0,P1,...,Pnを求めればよい。この計算をBスプライン補間とよんでいる。

 この計算は、(1)式のP(t)がt=iのときの
   P(i)=Qi (i=0,1,...,n)  (2)
を満たす制御点P0,P1,...,Pnを求めることになる。

 3次のBスプライン曲線の場合、N3(0)=4/6,N3(1)=1/6,N3(i)=0(i=<2)である。したがって、(2)式は、1=<i=<n-1に対しては
   (Pi-1+4Pi+Pi+1)/6=Qi  (3)
となり、i=0,nに対してはP-1=P0,Pn=Pn+1であるから
   (5P0+P1)/6=Q0  (4)
   (Pn-1+5Pn)/6=Qn   (5)
となる。

 (3)~(5)式は、P0,P1,...,Pnのx座標を変数とする連立方程式、y座標を変数とする連立方程式からなる。したがって、それぞれ解けば、P0,P1,...,Pnを求めることができる。

 次に、(1)式を(i;0=<t<1)の区間ごとに切り分けることにし、必要に応じて関数N3(t)を各区間に適用できるような形式に変形する。
   f1=(3t^3-6t^2+4)/6
   f2={-3(t-1)^3-6(t-1)^2+4}/6
   f3=-(t-1)^3/6
   f4=t^3/6

 そうすると、各区間のP(t)は、次に示す4つの項の重ね合わせとして表記できる。
   P(t)=f3P-1+f1P0+f2P1+f4P2   (i=0;0=<t<1)
   P(t)=f3P0+f1P1+f2P2+f4P3   (i=1;0=<t<1)
          ...
   P(t)=f3Pn-2+f1Pn-1+f2Pn+f4Pn+1   (i=n-1;0=<t<1)

 ここでは、Q0とQnで生じる可能性のあるオーバーシュートを避けるために、P-2とPn+2の項をもつ(i=-1;0=<t<1)と(i=n;0<t<1)の区間のP(t)を計算しないことにした。

 Excelを用いてスプライン曲線でだるまを描くことにした。

 だるまの中心線に沿ってy軸をとる。だるま全体の輪郭はこの中心線に関して左右対称とする。だるまの台の最下端を原点にとる。全体像の右輪郭線をP0,P1,...,P5の6点で表現する。ここでQ0とQ5はy軸上に設定する。左輪郭線のP0,P1,...,P5は、右輪郭線の対応するPiのx座標値を反転したものになるはずである。対応するPiのy座標値は変わらない。問題は、点Q0とQ5において左右の輪郭線がなめらかに連結するか否かということになる。

 だるまの顔の輪郭線についても、同様に左右対称とし、右輪郭線を6点で表現し、左輪郭線はその左対称線とした。だるまが乗る台の輪郭線も、同様に左右対称とし、3点で表現した。だるまの口も3点で表現できる。

 だるまの全体像の最下部は直線状をしているので、曲線で表現できない。直線で表現して上部の曲線に接続することにした。だるまが乗る台も同様に直線部分は直線とし、下部の曲線に接続した。

 だるまの目玉は、円で表現することにした。目玉の色を黒色にするために、グラフの系列を変える。

 Excelの表で必要な列は、tの刻みをつくる列、xの列、系列1のy列、系列2のy列の4列だけである。

 下図は、出来上がっただるまのイラストである。



 スプライン曲線でイラストのような図形を描くとき、その計算の準備や計算結果をグラフ表示して意図するような図形に修正する作業の手間ひまは大きい。今回作業の目的は、スプライン曲線を使ってこのような図形を描けることを確認することにあった。

 ただ、一つの図形を描くための作業量は大きいが、図形が一つできれば、それを別の場所に移動することは比較的容易にできる。したがって、同じ図形の繰り返しパターンをもつ模様などには有効に利用できるのではなかろうか。

 参考文献
 杉原厚吉著「形と動きの数理」(東京大学出版会)
 杉原厚吉著「インターネット時代の数学―グラフィックスのための幾何学」(共立出版)

最新の画像もっと見る

コメントを投稿

サービス終了に伴い、10月1日にコメント投稿機能を終了させていただく予定です。