三角関数フィッティングによる主方向の導出


~Kanoさんに捧ぐ~




■はじめに

先日、Kano さん達と呑んだときに、ハッチングの話になりました。
「ハッチングのテクスチャーは主曲率の方向に張るのがいいと考えられるが、 一般に、ポリゴンモデルがあったときに主方向を求める方法は定かではない。」との話になりました。
そこで、求める方法を適当に考えてみました。

■考え方

主方向とは、パラメータで与えられた曲線

p = p(u,v)

に関して、接ベクトル

pp
pu = ――,  pv = ――
     ∂uv

を定義出来ます。この曲面を局所的に展開した場合に、u0, v0の周りでは、

p(u0+du, v0+dv) = p(u0,v0) + dupu + dvpv
                   + [du dv]┌ pupu  pupv ┐┌du  pvpu  pvpv ┘└dv┘+・・・

と、展開できます(曲面の方向微分がC2級ぐらい必要かな?)。
2次の係数を与える行列を対角化した場合、その固有ベクトルをベクトルを主方向といいます。
主方向は、2次曲面で分解したときの方向を規定し、それぞれ直交します。

さて、曲面から、無限小だけ離れた領域を考えます。
この領域に関して、接ベクトルでつくる角度と、曲線の法線方向の成分をプロットすると、一つのグラフが描けます。

例えば曲面が楕円面のときの底面の点でのグラフはサインカーブになります。
それ以外の場合でも、曲面が2次までの範囲で、同じような曲線になります。
ここで「同じような」というのは、主方向が関数の山や谷になっている周期πの周期関数ということです。
周期関数があればフーリエ展開したくなるのが世の常というものです。
サンプリングが等間隔ではないので、フーリエ展開はできないのですが、三角関数のフィッティングを行い、その位相から主方向を求めます。

■計算方法

ポリゴンの頂点をpとします。
頂点は、n個の頂点viと隣接しています。
viへのPからの方向ベクトルをdvi = vi-pで定義します。
頂点pでの法線ベクトルをNNに直交する接ベクトル基底をUVとします。
dvi を規格化したベクトルに関して、U及びVとの内積から得られる角度を横軸、 Nとの内積を縦軸にしてグラフを作ります。

      N・dvi
di = ―――
      |dvi|
             V・dvi  U・dvi
θi = atan2(―――, ―――)
             |dvi|  |dvi|

この点列に関するフィッティングを行います。
周期πの関数でフィッティングしたいので、

f = A cos(2θ) + B sin(2θ)

の関数を考えます。
AとB、それぞれの係数を別々に求めます。
フィッティングするための誤差関数は、

errA = Σi(di - A cos(2θi))2,
errB = Σi(di - B sin(2θi))2

を使います。この誤差関数の値が小さくなるA及びBが各点列にもっとも近い関数fを与えます。
極値の条件、

    ∂errA
0≡ ――― = -2Σi(di - A cos(2θi))cos(2θi),
     ∂A

    ∂errB
0≡ ――― = -2Σi(di - B sin(2θi))sin(2θi),
     ∂B

から係数を求めると、

    Σi dicos(2θi)
A = ―――――――,
    Σi cos2(2θi)

    Σi disin(2θi)
B = ―――――――,
    Σi sin2(2θi)

になります。
この係数と、三角関数の公式

f = A cos(2θ) + B sin(2θ) = √(A2+B2) cos(2θ+ψ),
ψ = atan2(B, A),

から、位相が求まります。この位相が主方向になります。

■最後に

まさに机上の空論で、数値等で確認していないので、正しいのかわかりませんが、 頂点情報などの離散的な値から曲面という連続量を得るための方法の1つになるのではないでしょうか。




もどる

imagire@gmail.com