NURBS / BÉZIER CLIPPING

NURBS曲面のベジエクリッピング
交差判定・衝突判定・次数解析

第I部:曲面どうしの交差判定 第II部:球・三角形との衝突判定と貫通防止

ベジエクリッピング法は、もともと非有理(多項式)ベジエ曲線の交点計算として考案された手法だが、NURBS曲面が内部的には有理ベジエパッチの集まりに変換できることを使えば、曲面どうしの交差判定にも、動く球や三角形との衝突判定にもそのまま応用できる。本稿は2部構成で、第I部では2枚のNURBS曲面の交差線を求める方法(有理ベジエへの変換、ドーナツ・楕円体の厳密な枚数、従来手法との位置づけ、非有理近似の誤差)を、第II部ではその応用として、動く球・三角形とNURBS曲面の衝突判定(境界箱による前処理、貫通防止、そして n次の場合にクリップ平面からの距離関数・最近点探索がそれぞれ何次になるかという次数解析)をまとめる。
S1(u,v) = S2(s,t)   /   |S(u,v) − C| ≤ r 左:第I部が扱う交差条件(解は1次元の交差曲線) 右:第II部が扱う衝突条件(球の中心Cと曲面の最短距離)
第I部 曲面どうしの交差判定

1交差判定問題の定式化

2枚のパラメトリック曲面 S1(u,v)、S2(s,t) の交差線を求める問題(Surface–Surface Intersection、SSI)は、方程式としては単純だ。位置ベクトルの各成分(x, y, z)が一致する条件が3本、未知数は (u, v, s, t) の4個。条件数より未知数が1つ多いので、解は一般に1次元の曲線として現れる。

ただし、この方程式を素直にニュートン法などで解こうとすると難しい。非線形であるだけでなく、交差線が複数の成分(孤立したループなど)に分かれることがあり、良い初期値を与えないと一部の成分を見落とす。さらに2曲面が接するように交わる(接触交差)と、その近傍でヤコビアンがほぼ特異になり数値的に不安定になる。そこで、初期値なしに交差の「ある場所」を確実に見つけ出せる、大域的で頑健な手法が必要になる。ベジエクリッピング法はその代表格である。

2ベジエクリッピング法のしくみ

Sederberg と Nishita が1990年に曲線どうしの交点計算として提案した手法で、のちに曲面どうしの交差判定へも拡張された。核心は「制御点の凸包性」を使って、交差があり得ないパラメータ範囲を安全に、かつ大胆に削り落とすことにある。

2.1 曲線の場合(直感をつかむ)

曲線 C1(t) と C2(s) の交点を求めたいとする。まず C1 の制御多角形をすっぽり包む、平行な2直線の帯(FAT LINE)をつくる(帯の向きは、たとえば C1(0) と C1(1) を結ぶ直線を使う)。次に、C2 の各制御点からこの帯の中心線までの符号付き距離を計算する。距離は制御点の座標について線形な量なので、この距離の列は C2同じ次数のベジエ関数 D(s) の制御点になる。

ベジエ曲線は自分の制御多角形の凸包の中に必ず収まる(凸包性)。したがって D(s) のグラフも、その制御点がつくる凸包の中に収まる。この凸包が帯の許容範囲 [dmin, dmax] と重ならない s の範囲は、「その部分に交点はあり得ない」と確実に判定でき、切り捨てられる。

d_max d_min C₁(t) と、これを包む FAT LINE 生き残る s の範囲 C₂ の制御点から作った D(s)
図1. 左:曲線 C₁ とその制御多角形を包む FAT LINE。右:C₂ の各制御点から FAT LINE 中心線までの符号付き距離を並べた、C₂ と同じ次数のベジエ関数 D(s)。D(s) は自分の制御点の凸包から出られないので、帯 [d_min, d_max] に重なり得ない s の範囲(緑の帯の外側)を確実に切り捨てられる。

切り捨てたあと、まだ範囲があまり縮まらない(目安として9割前後しか縮まらない)場合は、大きい方の曲線を t = 0.5 でデ・カステリョ分割して2つに分け、それぞれに対して再帰する。これを繰り返すと、両方の曲線の生存区間が急速に縮んでいき、最終的に両方とも直線とみなせるほど短くなったところで、直線どうしの交点として答えを確定する。

2.2 FAT LINE の具体的な作り方

C1 の制御点を P0, …, Pn とする。FAT LINE の中心線には、最も単純で計算コストの低い選び方として、両端点を結ぶ弦(コード)を使う。

方向ベクトル  d = Pn − P0
単位法線  n = d を90°回転させて正規化したもの(|n|=1)
中心線のオフセット  c = n·P0
P0,…,Pn 自身の符号付き距離  ei = n·Pi − c  (i = 0,…,n)
帯の厚み  dmin = mini ei,   dmax = maxi ei

C1(t) は自分自身の制御点の凸結合なので、ei の凸結合として計算される C1(t) の距離も必ず [dmin, dmax] に収まる。これが「C1 を確実に包む」ことの根拠であり、dmin, dmax中心線からのC1自身のはみ出し量そのものである(曲がりの少ない曲線ほど帯は薄くなり、クリップの効きが良くなる)。より精密には両端点でなく最小二乗フィットした直線を中心線に使う変種もあるが、実装が簡単な弦を使うのが一般的である。

2.3 距離関数 D(s) の式と次数

C2 の制御点を Q0, …, Qm とすると、2.2で求めた同じ n, c を使って各点の符号付き距離 fi = n·Qi − c (i = 0,…,m) を計算する。これをそのまま制御点として並べたベジエ関数が D(s) である。

D(s) = Σi=0m C(m,i) (1−s)m−i si  fi
C(m,i) は二項係数。D(s) は s についてのm次多項式——すなわち C1 の次数(n)ではなく、クリップされる側の曲線 C2 の次数 m と同じ次数になる。C1 の情報(次数nや形)は n, c という2つの定数だけを通じて使われ、D(s) 自体の次数には影響しない。

たとえば C2 が3次(m=3、制御点4個)なら D(s) = (1−s)3f0 + 3(1−s)2s f1 + 3(1−s)s2f2 + s3f3 という、ふつうの3次多項式になる。あとは D(s) の凸包(あるいは制御点を結んだ折れ線の上下包絡線)が帯 [dmin, dmax] と重ならない s の区間を求めればよい。

2.4 曲面の場合(FAT LINE → FAT PLANE)

曲面どうしでも考え方はそのまま拡張できる。一方の曲面パッチの制御点net全体を包む、平行な2枚の平面(FAT PLANE)を作る。もう一方のパッチの各制御点から、この平面までの符号付き距離を計算すると、これも制御点について線形なので、元のパッチと同じ次数の「距離曲面」(1変数ではなく (u,v) の2変数ベジエ関数)になる。凸包性より、この距離曲面が帯 [dmin, dmax] に入り得ない (u,v) の領域を切り捨てられる。1次元のときと違い、u方向・v方向をそれぞれ独立に絞り込む形で近似的に処理する。

2.5 FAT PLANE の具体的な作り方

パッチ P の制御点net Pjk(u方向 j = 0,…,p、v方向 k = 0,…,q)から FAT PLANE を作る。曲線のときの「両端点を結ぶ弦」に対応するのが、ここでは「4隅の対角線」である。

対角線ベクトルの外積  n0 = (Pq,p − P0,0) × (Pq,0 − P0,p)  (4隅を結ぶ2本の対角線)
単位法線  n = n0 / |n0|  (ほぼ0なら別の3隅から作り直す)
平面のオフセット  d = n·G  (G は全 (p+1)(q+1) 個の制御点の重心)
P 自身の符号付き距離  sjk = n·Pjk − d  →  帯の厚み [lo, hi] = [min sjk, max sjk]
相手パッチ Q の符号付き距離  Fjk = n·Qjk − d  (これをクリップに使う)

曲線のときの dmin, dmax が [lo, hi] に、ei が sjk に、fi が Fjk に、そのまま対応している。平面を通す点に重心を使うのは、4隅だけでなく制御点net全体のバランスを取るための実務上の工夫で、必須ではないが安定した挙動になりやすい。

2.6 距離曲面の式と次数(有理曲面を含む)

Fjk を制御点として並べたのが距離曲面 f(u,v) である。

f(u,v) = Σj=0p Σk=0q Bjp(u) Bkq(v)  Fjk
Bjp, Bkq はベルンシュタイン基底。f(u,v) は相手パッチ Q と同じ双次数 (p,q)——制御点数 (p+1)×(q+1) が Q とそろった、2変数のベジエ関数になる。P の次数は法線 n とオフセット d という定数2つに畳み込まれるだけで、f 自身の次数には表れない。

Q が重み wjk を持つ有理パッチの場合、真の距離は f(u,v) = [n·X(u,v) − d·W(u,v)] / W(u,v) という分数式になる(X は重み付き制御点、W は重みだけのベジエ関数)。ただし重みが正である限り分母 W(u,v) は常に正なので、[lo,hi] に入り得るかどうかの判定には分子だけで十分であり、次数は上がらない。

重み付き制御係数  Njk = wjk·Fjk = wjk(n·Qjk − d)  (これも (p,q) 次)
G1,jk = Njk − hi·wjk = wjk(Fjk − hi)  →  これが0以下になり得るかを判定
G2,jk = Njk − lo·wjk = wjk(Fjk − lo)  →  これが0以上になり得るかを判定

実装上は、この2次元の判定を u方向・v方向それぞれ独立に行う。たとえばu方向を絞り込むときは、各 j について k方向の最小値 mink G1,jk を取って「u だけの」次数pのベジエ関数を作り、それが0以下になり得る u の範囲を求める(G2側は最大値 maxk G2,jk を使い0以上になり得る範囲を求める)。両方の範囲の共通部分が生き残る u 区間になる。v方向も同様に行い、絞り込めた (u,v) の矩形だけを残して分割・再帰する。

  1. 境界箱による棄却2枚のパッチの制御点が作る軸平行境界箱が重ならなければ、その時点で交差なしと確定できる(最も安価な足切り)。
  2. FAT PLANE クリップ一方のパッチを包む FAT PLANE を作り、他方のパッチをその帯に入り得る (u,v) 範囲へ収縮する。これを両方向について行う。
  3. 4分割して再帰クリップしてもあまり縮まらなければ、より「曲がっている」方(平面からのズレが大きい方)のパッチを u = v = 0.5 で4分割し、それぞれの組み合わせについて手順1〜3を再帰する。
  4. 末端処理両方のパッチが十分平らになったら、それぞれを平面四辺形(三角形2枚)とみなし、三角形どうしの交線を線分として取り出す。これをすべての末端ペアについて集めると、交差曲線の折れ線近似が得られる。

この4段構成(境界箱棄却 → FAT PLANE クリップ → 4分割再帰 → 末端の平面近似)が、ベジエクリッピング法によるSSIのすべてである。

2.7 交差線を構成する線分の正体

最終的に描かれる「交差曲線」は、実は1本の滑らかな曲線として直接求まっているわけではない。手順4(末端処理)で見た通り、再帰を打ち切った時点のパッチはもう曲面としては扱われず、制御点net の4隅だけ(P0,0, P0,p, Pq,p, Pq,0)を結んだ平面四辺形に置き換えられ、これが対角線で2枚の三角形に分割される。曲面A側の末端パッチも曲面B側の末端パッチも同様に「2枚の三角形」になるので、両者の間で最大 2×2 = 4通りの三角形の組ができ、それぞれについて平面同士の交線を三角形の範囲内に切り詰めた線分を求める。

出力される1本1本の線分 =「曲面Aの、これ以上分割できないくらい細かくなった1枚の末端パッチを平面近似した三角形」と「曲面Bの、同様に細かくなった1枚の末端パッチを平面近似した三角形」の、三角形どうしの交線
曲面Aの末端パッチ(三角形×2) 曲面Bの末端パッチ(三角形×2) この重なり合う三角形どうしの交線が、出力される線分1本
図3. 再帰の末端では両曲面のパッチが平面四辺形(三角形2枚ずつ)に置き換わる。出力される交差曲線は、こうしてできた無数の小さな三角形どうしの交線をすべてつなぎ合わせた折れ線であり、細分化の深さ(許容誤差)の範囲でしか元の滑らかな曲面には一致しない近似である。

つまり交差線を構成する各線分は、元のNURBS曲面や有理ベジエパッチそのものの交線ではなく、再帰的な絞り込みの果てにできた、極小の平面近似どうしの交線である。再帰の深さ(本稿の付属ツールでいう「再帰分割深度」)や平坦度の許容誤差を細かくするほど、この折れ線は元の滑らかな交差曲線に近づく。ただし第6章で見るように、これは出力側の近似精度の話であり、入力となる曲面そのものが非有理近似で歪んでいれば、出力をどれだけ細かくしてもその歪みまでは取り除けない、という点には注意が要る。

3NURBSから有理ベジエパッチへの変換

NURBS曲面は制御点 Pij、重み wij、そして2方向のノットベクトル U, V で定義される、いわば「多くの区間で制御点を使い回す」効率的なデータ構造である。ベジエクリッピング法は、各パッチが他と独立した固定サイズの制御点netであることを前提にしているので、そのままでは使えない。そこで必要になるのが、NURBSを「区間ごとに独立した有理ベジエパッチの集まり」へ変換する操作である。

3.1 一般の場合:ノット挿入によるベジエ分解

一般には、内部の各ノットの重複度が「次数と同じ」になるまでノット挿入を繰り返す(Boehm のアルゴリズム)ことで、幾何形状を一切変えずに NURBS をベジエ形式へ分解できる。これは任意の次数・任意のノット構造に対して機械的に適用できる、標準的かつ厳密(近似なし)な操作である。

3.2 円・楕円の場合:閉じた式によるショートカット

円弧や楕円弧に限っては、ノット挿入を経由しなくても最初から「ベジエ形式」の有理2次曲線として直接書き下せる。中心 C、(直交している必要のない)軸ベクトル U, V を使って P(θ) = C + cosθ·U + sinθ·V と表される弧(Δθ = θ1 − θ0 が180°未満)は、次の3制御点・3重みの有理2次ベジエで厳密に再現できる。

P0 = P(θ0),   P2 = P(θ1),   P1 = C + [cosθm·U + sinθm·V] / cos(Δθ/2)
w0 = 1,   w1 = cos(Δθ/2),   w2 = 1
(θm = (θ01)/2。Δθが180°に近づくほど w1→0 に近づき数値的に不安定になるため、実務上は1周を3〜4分割以上にして各弧を120°以下に保つ。)
P₀ (w=1) P₂ (w=1) P₁ (w=cos45°≈0.707) C 90°の弧を表す有理2次ベジエ(緑の弧=厳密に円弧と一致)
図2. 90°の円弧を厳密に表す有理2次ベジエ。中間の制御点 P₁ は円周の外側(接線の交点)にあり、重み w=cos45°≈0.707 が「外に出過ぎる分」を補正することで、緑の弧が円周と完全に一致する。

3.3 回転体・アフィン変形への拡張

トーラスや円柱のような回転体は、この弧の式を2方向に組み合わせる(母線方向の弧 × 回転方向の弧のテンソル積、重みは両者の積)ことで、厳密な有理ベジエ曲面になる。三軸の長さが異なる一般の楕円体は、まず単位球を上と同じ方法で回転体として構成し、そのあと制御点だけに (rx, ry, rz) のアフィン拡大縮小を掛ければよい(アフィン変換は重みを変えずに制御点だけ動かしても厳密性を保つ、という有理ベジエの性質を利用している)。

4ドーナツ・楕円体は何枚の有理ベジエパッチになるか

弧1本あたりの掃引角を180°未満(実務上は数値安定性のため120°以下)に保つ必要があるので、1周(360°)を有理2次ベジエで覆うには最低3分割が要る。半周(180°)だけなら2分割で足りる。これをふまえた実装上の分割数と、できあがるパッチの枚数は次の通り。

形状方向ごとの分割パッチ枚数1パッチの制御点数備考
ドーナツ(トーラス) 主円 4×90°
断面円 4×90°
4 × 4 = 16 3×3(双2次) 主円・断面円ともに1周360°。理論上の最小は3×3=9枚(120°刻み、重み0.5)だが、重みが1に近く数値的に穏やかな4分割を採用。
楕円体 経度 4×90°
緯度 2×90°
4 × 2 = 8 3×3(双2次) 単位球を回転体として構成し、あとから (rx,ry,rz) でアフィン変形。緯度方向は極から極まで180°なので2分割で最小かつ十分。
円柱(側面) 周方向 4×90°
高さ方向 1(直線)
4 × 1 = 4 3×2(2次×1次) 高さ方向は直線なので非有理・1次の2点で厳密。分割不要。周方向の重みだけが1でない混合次数パッチになる。

ここで重要なのは、いずれも「近似ではなく厳密」だという点である。ドーナツは16枚、楕円体は8枚という数字は分割の仕方(4分割 vs 最小3分割など)によって変わるが、どの分割を選んでも各パッチは円・楕円の弧を寸分違わず再現する。一方、次章以降で見るように、これを非有理の多項式ベジエで代用すると、パッチを何枚に増やしても厳密にはならず、有限の誤差が残り続ける。

5NURBSへの拡張に新規性はあるか — 従来手法との比較

結論から言うと、ベジエクリッピング法を有理ベジエ/NURBSへ拡張すること自体に、研究上の新規性はない。凸包性は重みが非負であれば有理ベジエでも成り立つことがNURBSの標準的な教科書(例えばPiegl & TillerのThe NURBS Book)でも述べられている既知の事実であり、SSIを主要テーマとするCAGD分野の文献や実務のCADカーネルでは、以前から有理曲面を意識したクリッピング/分割系のアルゴリズムが使われてきた。

その上で、本稿と付属ツールが明示的に書き下した実務上のポイントは新規ではないにせよ、教科書的な説明では省略されがちで書き留める価値がある。それは、有理曲面の距離関数 f = (分子)/(分母) は分母(重みの総和)が常に正である限り、符号や帯への出入りの判定を分子だけで行えるという点である。制御点ごとに wij·(距離) という重み付き係数を作るだけで、非有理の場合と同じ次数のベジエ関数のままクリッピングできる。明示的な除算も、微分による次数の上昇も必要ない。

手法頑健性(見落としの少なさ)収束の速さNURBSへの適用実装の手間
有理ベジエクリッピング
(本稿の手法)
高い(初期値不要) 速い(帯が細く絞り込みが強い) 直接可能 中(凸包判定・分割の実装が要る)
マーチング法
(追跡法・ニュートン法ベース)
低い(種点が要る・孤立ループを見落としやすい) 非常に速い(局所的には2次収束) 直接可能 低〜中
単純な境界箱分割
(FAT PLANEを使わない再帰分割)
高い 遅い(境界箱だけでは絞り込みが弱い) 直接可能(有理・非有理を問わない)
多角形近似
(両曲面を細かく三角形分割して交差)
分割密度に依存 分割密度に依存 直接可能 低(実装は容易)
代数的(陰関数化) 理論上は完全 高次数では実用不可 次数が上がると破綻しやすい 高い(数式処理が必要)
区間ニュートン法 高い(解の存在を保証) ノードあたりのコストが高い 直接可能 高い

この整理から見えてくるのは、有理ベジエクリッピング法の立ち位置である。マーチング法のような速さはないが種点なしに全ての交差成分を確実に見つけられ、単純な境界箱分割や多角形近似のような頑健さを保ちながら、FAT PLANEという線形な絞り込みのおかげでずっと少ない再帰回数で収束する。そして本稿の主題である「NURBSへそのまま使える」という性質のおかげで、非有理ベジエへ変換して精度を落とす、という妥協が不要になる。次章では、その妥協がどれほどの精度低下を招くのかを具体的に確認する。

6非有理ベジエで近似するとどれくらいズレるか

円弧・楕円弧は非有理(多項式)ベジエでは有限次数では厳密に表現できない。ここでは2種類の非有理近似について、実際にどれだけの誤差が出るかを数値で確認する。

6.1 定番の「マジックナンバー」近似(1本の3次ベジエで90°)

CGでよく使われる κ = 4/3·(√2−1) ≈ 0.55228 という係数を使った3次ベジエによる90°円弧近似は、半径に対して最大で次の誤差を持つ(実際に数値計算して確認した値)。

最大半径誤差 ≈ 0.0273 % (半径1に対して約0.00027)

1本の弧としては非常に小さいが、それでもゼロではない。これに対し、有理2次ベジエによる同じ90°弧は、浮動小数点の丸め誤差(10−16程度)を除いて完全に一致する。

6.2 円をN分割した非有理3次(Hermite)近似の収束

位置と接線ベクトルを一致させる3次エルミート補間(本稿の付属ツールで最初にトーラス・楕円体を作っていた方式と同じ構成)で円をN分割したときの、最大半径誤差の推移を計算した。

分割数 N(1周360°)1区間あたりの角度最大半径誤差誤差(%)
2180°0.2146 r21.460 %
3120°0.0466 r4.655 %
490°0.0152 r1.521 %
845°0.00098 r0.098 %
1622.5°0.00006 r0.006 %
3 または 4
(有理2次ベジエ)
120° または 90°≈10−16 r厳密(機械精度)

誤差はおよそ N−4で減っていく(Nを2倍にすると誤差はおよそ1/16になる)。つまり分割を増やせばいくらでも小さくできるが、ゼロにはならない。これに対して有理2次ベジエは分割数によらず常に厳密である。

本稿の会話の出発点になった最初のドーナツ・楕円体のコードは、断面円を N=2(180°ずつ)のエルミート3次近似で作っていた。上の表に当てはめると、断面半径に対して約21%もの誤差を持つ形状だったことになる — もはや「近似的なドーナツ」とは呼べない大きさである。

6.3 交差線そのものへの影響

形状の誤差は、そのまま交差線の誤差になる。付属ツールの既定配置(ドーナツ R=2.2, r=0.9、曲面Bを一枚差し込んだ状態)で、実際に「重みを使う(有理)」計算と「重みを1とみなす(非有理扱い)」計算を比較した。

曲面Bの制御点の重み交差線分数(有理)交差線分数(非有理扱い)対応点どうしの最大ズレ
すべて w=1(重みなし)255253ほぼ 0(数値誤差の範囲)
2点だけ w=3.0 と w=0.3 に変更245253断面半径の 26.3%

重みがすべて1(実質的に非有理と同じ)であれば当然ながら両者はほぼ一致する。しかし制御点の重みに意味のある差(3.0や0.3)を与えたとたん、重みを無視する近似は交差線を断面半径の4分の1以上も動かしてしまう。この大きさのズレは、クリッピングの再帰深度や平坦度の許容誤差をどれだけ細かくしても解消できない — 誤差の原因は数値計算の精度ではなく、入力する形状そのものが違うことにあるからである。

6.4 まとめると

7まとめ

第II部 球・三角形との衝突判定

第I部で導入した有理ベジエクリッピングの部品(FAT平面クリップ・凸包性・4分割再帰)をそのまま使い、動く球や三角形とNURBS曲面がぶつかっているかどうかを判定する。

1衝突判定と交差判定はどう違うか

前稿で扱った交差判定(SSI)は、2枚の曲面 S₁(u,v)=S₂(s,t) を満たす (u,v,s,t) を求める問題で、答えは1次元の曲線だった。本稿の衝突判定は問いの形が違う。球なら「中心 C から曲面までの最短距離が半径 r 以下か」という不等式、三角形なら「曲面と実際に交わっているか」という真偽値を求めればよく、交差線という連続的な形状そのものは要らない。

この違いは計算の設計に直結する。交差判定では曲面全体を細かく追跡する必要があったが、衝突判定は「イエスかノーか」と「(必要なら)どこで」が分かればよいので、関係ない部分を早い段階でどんどん切り捨てることに集中できる。実際、本稿の手法は前稿のベジエクリッピングの部品(FAT平面クリップ・凸包性・4分割再帰)をほぼそのまま再利用しつつ、末端の扱いだけを衝突判定向けに変えたものになっている。

2球の衝突判定:境界箱と最短点

有理NURBS曲面 S(u,v) 上で中心 C までの距離を最小化する厳密な最短点を求めるには、距離の2乗 |S(u,v)−C|² を u, v で偏微分してゼロになる点を解く必要がある。S が有理式(分子/分母)だと、この偏微分は商の微分則を通るため分子の次数が跳ね上がり、しかも解は非線形連立方程式になる——曲面が動くたびに毎フレーム解くには重すぎる。

2.1 境界箱(6平面)による前処理

そこで、真の最短点を解く前に、中心 C・半径 r の球を包む一辺 2r の立方体(軸平行境界箱、6平面)で候補パッチを絞り込む。前稿で導入した FAT平面クリップの関数 clipToSlab(P, {n, d}, lo, hi) は、平面の法線 n・オフセット d と、帯の範囲 [lo, hi] さえ与えれば、どんな平面に対しても使える汎用の道具だった。軸平行境界箱の6面は、法線が単に x, y, z 軸方向であるだけの特殊なFAT平面なので、同じ関数がそのまま使い回せる

x軸:clipToSlab(P, {n=(1,0,0), d=0}, Cx−r, Cx+r)
y軸:clipToSlab(P, {n=(0,1,0), d=0}, Cy−r, Cy+r)
z軸:clipToSlab(P, {n=(0,0,1), d=0}, Cz−r, Cz+r)
3回のクリップで (u,v) の候補範囲を絞り込み、4分割して再帰する。境界箱に絶対入り得ないパッチは早々に棄却される。

2.2 点と三角形の最短点(微分なし・閉じた式)

再帰的な絞り込みで末端まで来た小さなパッチは、4隅の制御点(=有理ベジエでも厳密に曲面上にある点)を結んだ平面三角形2枚で近似する。あとは「点 C から、この小さな三角形までの最短点」を求めればよく、これは Ericson の Real-Time Collision Detection にある標準的な閉じた式で厳密に解ける。三角形を7つの領域(頂点3・辺3・内部1)に分け、C がどの領域の真上にあるかを内積だけで判定する。

A B C 面の領域 頂点の領域(Aの例) 辺の領域(ABの例)
図1. 三角形の周りは7つの領域(頂点3・辺3・面1)に分かれる。点 C がどの領域にあるかによって、最短点は「頂点そのもの」「辺上に垂線を下ろした点」「面上に垂線を下ろした点」のいずれかに確定する。すべて外積・内積の符号判定だけで、反復計算なしに求まる。

この2段構え——境界箱で候補を絞り込み、末端では閉じた式で決める——によって、S(u,v) の微分を一度も計算せずに、有理NURBS曲面までの最短距離(が半径以下かどうか)を判定できる。

3三角形の衝突判定:厚み0の5面体

動く物体が三角形(ポリゴンメッシュの1枚を想定)の場合、球のような「中心と半径」という単純な指標がない。ここでは境界箱の代わりに、三角形自身がつくる厚み0の5面体(三角柱)を使う。

三角形の平面1枚を薄いスラブ [−ε, +ε] として使う(上下2面ぶん)
3つの辺それぞれを、三角形の法線方向に押し出した半空間(3面)
あわせて実質5面。これも clipToSlab をそのまま呼ぶだけで実装できる——法線が三角形自身の法線や辺の法線に変わるだけで、仕組みは球の境界箱と同じ。

軸平行境界箱よりずっとタイトに絞り込めるため、実測(本稿のツールと同じドーナツ形状で)で判定ノード数・候補パッチ数が6〜8倍少なくなることを確認している。末端まで絞り込んだあとは、候補パッチの三角形と衝突オブジェクトの三角形の、三角形どうしの交差判定(前稿と同じ triTriSegment)で最終確定する。

4貫通防止(トンネリング対策)

アニメーションは離散的な時間刻みで進む。物体が小さい・速いと、ある1フレームでは表面の手前、次のフレームではもう表面の向こう側——という具合に、間の瞬間に触れていたはずなのに、サンプリングした2点のどちらでも交差が検出されないことが起こる。これが貫通(トンネリング)である。

4.1 球:半径拡張法

1タイムステップで物体が進んだ距離を L とする。判定に使う半径を r ではなく r+L にするだけで、この見逃しを防げる。根拠は三角不等式である。

半径 r の球を距離 L だけ直線的に動かした「スイープ領域」(両端が半球のカプセル形)を考える。
このカプセルに含まれる任意の点 P は、ある瞬間の球の中心 Q(始点から終点までの線分上のどこか)から半径 r 以内にある。
終点を B とすると、|P−B| ≤ |P−Q| + |Q−B| ≤ r + L(三角不等式、かつ |Q−B|≤L)。
つまりカプセル全体が、終点 B を中心とする半径 r+L の球に完全に含まれる。だから終点だけを見て「半径 r+L 以内か」を判定すれば、スイープの途中で触れたケースを取りこぼさない。
始点(半径r) 終点B(半径r) スイープ領域(カプセル) 半径 r+L の円(終点中心) L
図2. 青いカプセル(球が距離Lだけ動いた領域)は、必ず終点を中心とする半径r+Lの円(オレンジ)に完全に含まれる。だから終点だけを見て半径r+Lで判定すれば、スイープの途中の接触も逃さない——三角不等式そのものが証明になっている。

4.2 三角形:スイープした5面体

三角形の場合は、進行方向(sweepベクトル、前フレームから今フレームへの移動量)に三角形を押し出した立体を使う。これは3.の静止した三角形の5面体とまったく同じ構造になる——2枚の平面(始点側の三角形の平面・終点側の三角形の平面。並進移動なので法線の向きは変わらない)を薄いスラブとして1面、3つの辺をそれぞれ sweep 方向に押し出した平行四辺形の半空間を3面。あわせてやはり5面であり、面の数は静止時と同じまま、計算コストは増えない。sweep がゼロに近づけば自動的に静止版の式に一致する。

始点の三角形 終点の三角形 sweepベクトル方向に押し出した3枚の側面
図3. 三角形をsweepベクトル方向に押し出すと三角柱ができる。2枚の三角形の面(始点・終点)+3枚の側面(各辺を押し出した平行四辺形)=5面。この5面体の内部に曲面が触れていれば、スイープの途中で接触したとみなす。

5見落としていたケースとその修正

実装の最初のバージョンでは、三角形の貫通防止の最終判定を「候補パッチの三角形の3本の辺が、スイープした5面体を横切るかどうか」で行っていた。多くの場合はこれで正しく動くが、実際に負荷テストをしたところ、衝突オブジェクトを小さく・速くすると見逃しが残ることが分かった。

原因は次の通りである。スイープした5面体(三角柱)は衝突オブジェクト自身の大きさで決まる。オブジェクトが十分小さいと、この5面体が曲面側の候補パッチ(三角形)よりも小さくなることがある。そうなると、5面体が候補パッチの面の内側を貫通するのに、パッチの辺には一度も触れない——辺だけを見る判定はこのケースを取りこぼす。

たとえば、一辺1の大きな候補パッチの三角形の中央付近を、直径0.1程度の細い5面体がまっすぐ突き抜けたとする。5面体は確かにパッチのを貫通しているが、パッチのには一度も交わらない。辺だけをチェックする実装は、この明白な接触を「なし」と誤判定してしまう。

修正は、候補パッチの三角形そのものを5面体の各面で順に切り詰めていく方法(Sutherland–Hodgmanのポリゴンクリッピング)に変更することだった。5枚の半空間で三角形を順番にクリップし、最後に何かしらの多角形が残っていれば接触とみなす。この方法は「5面体が三角形の辺を横切る」場合と「5面体が三角形の内部だけを貫通する」場合の両方を、区別なく正しく検出できる。

検証条件(負荷テスト)真の衝突回数貫通防止 OFF・見逃し貫通防止 ON(修正後)・見逃し
球・半径0.10・最高速度・左右往復軌道3680
三角形・一辺0.10・最高速度・左右往復軌道2880

実際のアニメーションループを再現した負荷テスト(150ステップ、細かい時間刻みでのブルートフォース判定を「正解」として比較)で、修正後は球・三角形とも見逃しゼロを確認している。

6従来手法との比較 — 新規性はあるか

結論から言うと、ここで使った個々の要素技術——球の半径拡張、三角形のスイープ体積、ポリゴンクリッピングによる交差判定——はいずれも衝突判定・コンピュータグラフィックスの分野で既に確立された手法であり、本稿に研究上の新規性はない。半径拡張法は「保守的前進(conservative advancement)」や「スイープ球(swept sphere)」としてゲーム物理エンジンで広く使われ、スイープ体積を使う連続衝突判定(Continuous Collision Detection, CCD)も1990年代から活発に研究されている、成熟した分野である。

その上で、本稿の実装が持つ実務上の特徴は、これらの標準的な考え方を前稿のNURBS向けベジエクリッピング基盤にそのまま統合した点にある。境界箱も、三角形のスイープ5面体も、結局は「法線と帯 [lo,hi] を持つ平面のクリップ」という同じ clipToSlab 関数を呼んでいるだけであり、有理曲面の重みも自動的に正しく扱われる(前稿で導入した「重み付き係数で次数を上げずに判定する」性質がそのまま効く)。専用の衝突判定パイプラインを別に書く必要がない、という点は地味だが実装上の利点である。

手法頑健性(貫通の有無)NURBSへの適用実装の手間備考
本稿の手法
(境界箱/5面体クリップ+半径拡張・スイープ体積)
高い(検証済み・見逃し0) 直接可能 前稿のクリッピング基盤を再利用
離散サンプリングのみ
(各フレームの位置だけ判定)
低い(貫通が起きる) 直接可能 実装は最も簡単だが、速い・小さい物体に弱い
GJK/EPA + 保守的前進
(凸包どうしの距離を反復計算)
高い 凸多面体近似が必要 高い ゲームエンジンで標準的。NURBSは事前に多面体近似するのが普通
投機的接触
(速度方向に境界を先読みして拘束を先に作る)
高い 多角形メッシュ向け 高い 物理エンジンで接触の「めり込み」防止に使われる、やや発展的な手法
時間刻みを十分小さくする
(サブステップ分割)
速度次第 直接可能 確実性はステップ数に依存し、計算コストとのトレードオフ

要するに、本稿の位置づけは「NURBSの厳密な形状表現と、確立された連続衝突判定の考え方を、同じベジエクリッピングの土台の上で自然につなげた」というところにある。個々の要素はどれも車輪の再発明ではないが、有理曲面の重みを特別扱いせずに済む形で貫通防止まで一貫して実装できる、という組み合わせ方には一定の実用的な価値がある。

7n次の場合の次数解析——距離関数と最近点探索

ここまでは球・三角形の側から衝突判定の仕組みを見てきたが、ここでNURBS曲面の次数 n(双次数 (p,q))を主役にして、「クリップ平面までの距離」と「真の最近点」がそれぞれ何次の式になるのかを具体的に導出する。後半の次数はここで実際にコンピュータ代数(sympy)を使って検証した値であり、既存の教科書の記述をそのまま引き写したものではない。

7.1 記法:双次数 (p,q) のNURBS曲面

u方向に次数 p、v方向に次数 q の有理ベジエ(NURBSを分解した1パッチぶん)を、制御点 Pij、重み wij(i=0,…,p、j=0,…,q)を使って次のように書く。

S(u,v) = X(u,v) / W(u,v)
X(u,v) = Σi,j Bip(u)Bjq(v)  wijPij  (ベクトル値、双次数(p,q))
W(u,v) = Σi,j Bip(u)Bjq(v)  wij  (スカラー値、双次数(p,q))
両方向の次数が同じ(p=q=n)ときは、単に「n次のNURBS曲面」と呼ぶ。曲線の場合は v 方向がなく、S(t)=X(t)/W(t)、次数 n の1変数版になる。以下ではまず曲線(1変数)で結果を導き、あとから曲面(2変数)に拡張する。

7.2 クリップ平面からの距離関数——次数は変わらない

平面(単位法線 、原点からの符号付き距離 d)までの符号付き距離は次の通り。

f(u,v) = ·S(u,v) − d = [·X(u,v) − d·W(u,v)] / W(u,v)
N(u,v) := ·X(u,v) − d·W(u,v)  (分子)
N(u,v) は X, W と同じ双次数 (p,q) である——法線・オフセットとの内積・スカラー倍は、Bernstein基底の次数を一切変えない線形演算だから。分母 W(u,v) は重みが正である限り常に正なので、帯 [lo,hi] への出入りは分子 N だけで判定できる(前稿で使った手法)。次数はもとの曲面と同じ (p,q) のまま、1段も増えない。

これは境界箱の6平面クリップでも、三角形のスイープ5面体クリップでも同じ構造だった——法線がどんな向きでも、距離関数の次数は常に元の曲面と同じままである。次章の最近点探索とは対照的な、良い性質である。

7.3 最近点探索を直接解くと何次になるか

点 C までの最短点を求めるには、距離の2乗 D(t) = |S(t)−C|² を微分してゼロになる t を解けばよい。これを実際に最後まで展開すると、どんな次数の多項式になるだろうか。

準備:分子だけの式に持ち込む

Y(t) := X(t) − C·W(t) とおくと、S(t)−C = Y(t)/W(t) なので D(t) = |Y(t)|² / W(t)²。商の微分則を適用し、分母 W(t)³ を払うと、D'(t)=0 は次の式と同値になる。

E(t) := Y(t)·Y'(t)·W(t) − |Y(t)|²·W'(t) = 0
Y は次数n、Y' は次数n−1(微分で次数が1下がる)、W は次数n。
「素朴に」次数を数えると:Y·Y'·W → n+(n−1)+n = 3n−1、|Y|²·W' → 2n+(n−1) = 3n−1。両方とも3n−1次に見える。

最高次の項がちょうど消える

ところが、実際に展開すると最高次の項(t3n−1 の係数)が恒等的に消えることが分かる。理由は次の通り。

Z(t) := X'(t)W(t) − X(t)W'(t)  (この式変形をすると E(t) = Y(t)·Z(t) に一致する。※C に依存する項が打ち消し合うため)
X, W はともに次数nの多項式。最高次の係数をそれぞれ an, bn とすると、X'(t) の最高次係数は n·an、W'(t) の最高次係数は n·bn
X'W の t2n−1 係数 = n·an·bn
XW' の t2n−1 係数 = an·n·bn
両方とも n·an·bn で完全に一致するので、差 Z=X'W−XW' の t2n−1 の項は消える。Z の次数は 2n−2 に下がる。

E(t) = Y(t)·Z(t) で、Y の次数は n、Z の次数は 2n−2 なので、E(t) の次数は n + (2n−2) = 3n−2。素朴な見積もりの 3n−1 より1つ低い。この結果は本稿執筆にあたり実際にコンピュータ代数(sympy)で n=1〜5 の乱数係数の有理曲線を作り、展開して次数を数えて確認した——理論的な見積もりだけでなく、具体的な数値でも一致している。

次数 n非有理曲線
(2n−1次)
有理曲線=NURBS
(3n−2次)
1(直線・弧)11
2(2次)34
3(3次)57
4(4次)710
5(5次)913
6(6次)1116
1 1 n=1 3 4 n=2 5 7 n=3 7 10 n=4 9 13 n=5 11 16 n=6 非有理(2n−1) 有理NURBS(3n−2)
図4. 最近点を直接解いたときの多項式次数(青=非有理 2n−1、オレンジ=有理NURBS 3n−2)。有理化すると常に高くなり、差は n が大きいほど開いていく(3n−2 と 2n−1 の差はちょうど n−1)。

非有理(重み一定)の場合との対比

重みがすべて等しい(W が定数、W'=0)非有理の場合は、E(t) = Y·Y'·W がそのまま残り、Y=X−C(次数n)、Y'=X'(次数n−1)なので、E の次数は単純に 2n−1。これは古典的によく知られた「非有理ベジエ曲線の最近点は2n−1次の多項式を解けばよい」という結果と一致する。有理化すると、この 2n−1 が 3n−2 まで増える——差は n−1 で、n が大きいほど開いていく(図4)。

7.4 曲面(2変数)の場合

曲面 S(u,v)=X(u,v)/W(u,v)(双次数 (p,q))では、D(u,v)=|S−C|² を u, v それぞれで偏微分してゼロとおいた、2本の連立方程式を解くことになる。曲線の場合と同じ手順(Y=X−CW とおき、商の微分則を適用し、最高次の項の打ち消しを確認する)を u 方向・v 方向それぞれに適用すると、次の次数が得られる(これも実際に複数の (p,q) の組み合わせでsympyにより数値的に検証済み)。

∂D/∂u = 0  →  双次数 (3p−2, 3q) の方程式
∂D/∂v = 0  →  双次数 (3p, 3q−2) の方程式
微分した方向(u または v)だけ −2 の補正が入り、微分していない方向はそのまま3倍になる。非有理(W一定)なら、それぞれ (2p−1, 2q) と (2p, 2q−1) になる(曲線の場合の2次元版)。
n次(p=q=n)非有理曲面
2本の方程式の双次数
有理NURBS曲面
2本の方程式の双次数
n=1(1,2) と (2,1)(1,3) と (3,1)
n=2(3,4) と (4,3)(4,6) と (6,4)
n=3(5,6) と (6,5)(7,9) と (9,7)

2本の曲線(双次数の代数曲線)が (u,v) 平面上で交わる点の最大個数は、双次数 (a₁,b₁) と (a₂,b₂) の曲線どうしなら a₁b₂+a₂b₁ 個という、双次数版のベズー限界で見積もれる。p=q=n の有理NURBS曲面にこれを当てはめると、最大で 18n²−12n+4 個の臨界点(極大・極小・鞍点すべて含む)があり得ることになる——n=2 で52個、n=3 で130個。境界箱による前処理なしに、毎フレームこの数の解を持ちうる連立方程式を直接解くのは現実的でない。

7.5 次数が示すこと——境界箱による前処理の正当化

ここまでの結果をまとめると、有理NURBS曲面に対して行う2種類の操作は、次数の増え方がまったく違う。

この非対称性こそが、前2稿で採用した設計——「真の最近点を直接解く」のではなく「境界箱で候補パッチを絞り込み、末端では平面近似した三角形どうしの最短点(微分不要の閉じた式)で済ませる」——の理由である。距離関数(クリップに使う量)の次数が増えないという性質のおかげで、境界箱による絞り込み自体は速く行える。一方、真の最近点を解く操作は最後まで避け続け、十分小さくなった末端パッチでは「平面上の最短点」という定数次数(微分不要)の問題にすり替えることで、n がいくら大きくても計算コストが跳ね上がらないようにしている。

8まとめ(第II部)