⚠ ローカルファイルとして開いています。Chromeのセキュリティ制限によりコンソール警告が出ますが動作に影響はありません。

球・三角形 × NURBS曲面 衝突アニメーション

境界箱(6平面)による前処理クリップで候補パッチを絞り込んでから、末端パッチとの距離/交差だけを調べる。有理曲面の距離関数を直接微分せずに済ませるのが狙い
★ 曲面A(NURBS)
曲面A: 16 パッチ
★ 衝突判定オブジェクト
三角形
軌跡
周回
上から落下
左右往復
衝突したら停止
ONにすると衝突を検知した瞬間に運動を止めます(「落下」と組み合わせると着地のような見た目になります)。再生ボタンや「t=0に戻す」で解除されます。
貫通防止
物体が小さい・速いと1フレームで表面をすり抜けて衝突を見逃すことがあります。ONにすると、球は半径を1フレームの移動距離ぶん広げ、三角形は進行方向にスイープした5面体で判定することで、このすり抜けを防ぎます(衝突の正確な発生時刻までは求めない簡略版)。
再生中
t=0に戻す
★ 境界箱プリプロセス設定
境界箱6平面クリップを使う
OFFにすると境界箱の重なり判定だけで絞り込み、6平面によるクリップは行いません。判定ノード数の増え方の違いが統計に現れます。
表示設定
曲面A
衝突オブジェクト
候補末端パッチ
最短点マーカー
ワイヤ
パッチ境界線
統計
曲面Aパッチ数
判定ノード数
境界箱で棄却
6平面クリップで棄却
候補末端パッチ数
最短距離 / 状態
貫通防止OFF
衝突判定
検出回数(累計)0
計算時間
🖱 ドラッグ → 視点回転 🖱 ホイール → ズーム

球との衝突は「球の中心とNURBS曲面の最短距離 ≤ 半径」で判定する。有理曲面の場合、最短点を厳密に求めるには距離関数 f(u,v)=|S(u,v)−C|² を微分してゼロ点を解く必要があり、S(u,v) が分数式(有理式)だと分子・分母それぞれの微分が絡んで次数が跳ね上がり、 毎フレーム解くには重い。

そこで本ツールは、球を包む軸平行境界箱(6平面の6面体)を先に作り、同じ有理ベジエクリッピング(FAT平面クリップの特殊形=軸に平行な平面3組) で「箱に絶対入り得ないパッチ」を再帰的に削り落とす。生き残った、既に十分小さくなった末端パッチだけを4隅の平面三角形2枚に近似し、 三角形—点の最短距離(微分不要の閉じた式)で最終判定する。これにより、高次の微分計算を一度も行わずに衝突判定できる。

三角形モードでは軸平行境界箱ではなく、三角形自身がつくる厚み0の5面体(三角柱)をそのまま使う——三角形の平面1枚 (薄いスラブとして上下2面ぶん)+各辺を法線方向に押し出した半空間3枚=あわせて5面。軸平行境界箱より遥かにタイトに絞り込めるため、 実測で判定ノード数・候補パッチ数が数分の1(最大8倍程度)に減る。絞り込んだ末端パッチの三角形と衝突オブジェクトの三角形の、 三角形どうしの交差(前の解説ツールと同じ triTriSegment)で最終判定する。

衝突が確定した時点で探索を打ち切る(早期終了)ため、表示される最短点は衝突時には必ずしも真の最短点ではない(十分近いことは保証される)。 衝突していないときは候補が全く残らないことが多く、そのぶん判定は非常に高速になる。

色の意味:赤=そのフレームで衝突している、青/緑=衝突していない。ただし物体が小さい・速いと、実際に当たっている フレーム数がごく短く(1フレーム=約16msのこともある)、肉眼では赤をほとんど視認できないことがある。そこで見た目だけ、 衝突した瞬間から約0.3秒間は赤色表示を保持するようにしている(判定ロジックや統計欄の「衝突判定」自体はこの引き延ばしを 受けない、正確な瞬間値のまま)。統計欄の「検出回数(累計)」は、見た目に頼らず衝突が実際に検出された回数を数え上げたもの なので、赤が一瞬すぎて見えない場合はここで確認できる。

軌跡は「周回」「上から落下」「左右往復」の3種類から選べる。「上から落下」は一定周期で上空から重力落下し、地面付近まで 落ちるとまた上から降り直す(ループ)。「衝突したら停止」をONにすると、衝突を検知した瞬間に運動を止める——「落下」と 組み合わせると曲面に着地してそこに乗ったままになる見た目になる。

貫通防止(トンネリング対策):物体が小さい、または速度が速いと、1フレームの間に物体が完全に表面を通り抜けてしまい、 移動前・移動後どちらの位置でも交差しておらず衝突を見逃すことがある。この対策として、1タイムステップで進んだ距離を L とすると—— 球の場合は、最短距離の判定に使う半径を r から r+L へ広げて判定する。三角不等式より、半径 r の球を距離 L だけ動かした スイープ領域(カプセル)は、移動後の位置を中心とする半径 r+L の球に完全に含まれるため、この単純な拡張だけで すり抜けを確実に防げる。三角形の場合は、三角形を進行方向(sweep ベクトル)に押し出した、厚み0の5面体(三角柱)を 候補パッチの絞り込みと最終判定の両方に使う——面の数は静止した三角形のときの5面(平面1枚+辺3枚)と同じままなので、 計算時間は増えない。末端パッチの三角形をこの5面体の各面で順に切り詰めていき(ポリゴンクリッピング)、何か残れば 接触とみなす。なお、衝突が実際に何秒後(フレーム内のどの時刻)に起きたかまでは求めていない簡略版で、「このフレーム中の どこかで接触した」ことだけを判定する。

貫通防止ON時の表示:実際に判定に使っている拡張領域そのものをオレンジ色の破線で重ねて表示する——球なら 半径 r+L に広げたビルボード円(カメラの方を向く円)と、直前フレームの中心から今の中心への移動を示す線分。 三角形なら、スイープした5面体(三角柱)の輪郭をそのままワイヤーフレームで表示する(開始位置の三角形・終了位置の 三角形・それらをつなぐ3本の辺)。「衝突オブジェクト」の表示をOFFにすると、この可視化も一緒に消える。
NO COLLISION
視点: 左ドラッグ / ズーム: ホイール