スクリーン座標 (x, y) → ベジエ曲面上の UV 座標

点を拾う、三つのやり方

3次元ベジエ曲面をクリックしたとき、その画面座標に対応する曲面上の (u, v) を どう求めるか。「三角形化+ニュートン法」「ベジエクリッピング法」、そして 両者を組み合わせた「ハイブリッド法(クリップ→ニュートン切替)」という 性質の異なる三つのアプローチを、仕組み・精度・実測速度の観点で比較する。

共通の問題設定

カメラ(視点 E)から画面上の画素 (x, y) を通る視線レイを1本引くと、 レイが曲面 S(u, v) と交わる点はふつう1点か数点に限られる。 求めたいのは、その交点における曲面パラメータ (u, v) である。 ベジエ曲面はビキュービック(各方向3次)の制御点パッチで表され、 評価関数 S(u, v) は4×4個の制御点のバーンスタイン基底による重み付き和になる。

この「レイと曲面の交差点探索」は本質的にはレイトレーシングそのものの部分問題であり、 三角形化法はレンダリング(ラスタライズ)寄りの近似的な解き方、 ベジエクリッピング法はレイトレーシング用に考案された厳密寄りの解き方、 ハイブリッド法はその両者の良いところを繋ぎ合わせた実装、という立場の違いがある。

A  三角形化+ニュートン法

曲面をあらかじめ N×N のグリッドで細分し、各セルを2枚の三角形として 画面へ投影しておく。クリック点を含む三角形を重心座標でヒットテストし、 三角形の3頂点が持つ (u, v) を重心座標で線形補間して初期値を得る。 この初期値から出発し、画面上の誤差

F(u, v) = Proj( S(u, v) ) − (x, y)

が 0 になるよう、有限差分で求めたヤコビアンを使ってニュートン法を数回反復する。

∂Proj(S)/∂u ≈ ( Proj(S(u+ε,v)) − Proj(S(u,v)) ) / ε  (v方向も同様)
[Δu, Δv]ᵀ = J⁻¹ ・ ( (x,y) − Proj(S(u,v)) )
(u, v) ← (u, v) + (Δu, Δv)  を数回繰り返す
① 三角形メッシュへのヒットテスト click (x, y) 重心座標で (u,v) を線形補間 → ニュートン法で数回微修正 初期値からの収束(誇張表示)
図1 — 曲面をN×Nの三角形メッシュに分割し、クリック位置を含む三角形から重心座標で初期UVを得たのち、画面空間の誤差をニュートン法で数回反復して詰める。

長所

  • 実装が直感的で、点in三角形判定と補間だけで初期解が得られる
  • ほぼ常に1回の反復で高精度(誤差1px未満)に収束する
  • 複数曲面が重なる場合も、各パッチ独立に判定するだけでよい

短所

  • N×N分割のメッシュ生成コストが、交差の有無によらず必ずかかる
  • 分割が粗いと、細長い凹凸や急峻な曲率のある領域で三角形からクリックが外れ、 取りこぼす(偽陰性)ことがある
  • ニュートン法は局所収束のみ保証:初期値が悪いと発散・振動しうる
  • 「厳密に交差する」という数学的保証がなく、あくまで近似

B  ベジエクリッピング法

Nishita らが1990年にレイトレーシング用に提案した手法。視線レイを 「レイを含む2枚の平面の交線」として表現するのが出発点になる。 レイ方向 d に直交し互いにも直交する法線 n₁, n₂ を選び、レイ原点を o とすると、

g₁(u, v) = n₁ ・ ( S(u, v) − o )
g₂(u, v) = n₂ ・ ( S(u, v) − o )

という2つの3×3次ベジエ関数(スカラー値)ができる。S が制御点のバーンスタイン基底による 線形結合であることから、g₁, g₂ の制御係数は元の制御点を平面までの符号付き距離へ 射影するだけで直接求まる。レイと曲面の交点はまさに g₁(u,v) = 0 かつ g₂(u,v) = 0 となる (u, v) である。

凸包性による棄却とクリッピング

ベジエ関数の値は制御係数の凸包の内側に収まる(凸包性)。したがって g₁ か g₂ の制御係数が全て同符号なら、そのパッチ内に解は存在しないと 数学的に確定でき、即座に棄却できる。符号が混在する場合のみ、 列・行ごとの係数の最小値・最大値が作る「包絡線(ファットライン)」を用いて u 方向・v 方向の安全な範囲を求め、その範囲でパッチを切り詰める。

u方向の安全範囲 ← g₁の列ごとの最小/最大の包絡線 ∩ g₂の列ごとの最小/最大の包絡線
(切り詰めた後)v方向の安全範囲 ← 同様に行方向で g₁, g₂ の積集合
これを u → v → u → v … と交互に繰り返し、範囲を収縮させる

収縮が遅い場合(同一パッチ内に複数交点があるなど)は4分割し、 それぞれの子パッチで同じ手続きを再帰的に継続する。範囲の幅が 許容誤差(本アプリでは 0.001)を下回れば収束とみなす。

② UV空間での交互クリッピング(u→v→u→v…) u=0 u=1 v=0 v=1 u方向クリップ g₁, g₂ の列包絡線の積で u範囲を収縮 v方向クリップ 同様に行包絡線の積で v範囲を収縮 交互反復 → 交点UVへ収束 誤差が全曲面同符号なら即座に棄却
図2 — 矩形範囲 [u0,u1]×[v0,v1] を、u方向・v方向と交互に safeRangeBiv(列・行の包絡線)でクリップして収縮させ、最終的に交点の (u,v) へ収束させる。

長所

  • 凸包性により「解なし」を数学的に確定できる(誤って取りこぼすことがない)
  • あらかじめメッシュを作らないため、交差しないパッチをほぼ1回の判定で即座に切り捨てられる
  • 4分割フォールバックにより、同一パッチ内の複数交点(接線的な交差など)も扱える
  • 本来レイトレーシングのために考案された手法であり、レンダリング用途と親和性が高い

短所

  • 実装がやや複雑(ベジエ関数の係数演算・部分パッチ抽出が必要)
  • 収縮の速さは線形(1次収束)にとどまるため、範囲をごく小さくするまで u/v交互クリップを何度も繰り返す必要がある
  • 2枚のクリップ平面の選び方(法線 n₁, n₂)が数値安定性に影響する

C  ハイブリッド法(クリップ→ニュートン切替)

ベジエクリッピング法の弱点は、範囲を許容誤差まで収縮させる終盤の反復が 線形収束であること。凸包性による確実な足場を得たあとまで、 同じ調子でクリップを続けるのはやや非効率になる。 一方でニュートン法は初期値さえ良ければ2次収束(1反復ごとに有効桁数がほぼ倍増) する。そこで、両者の得意な局面だけを使う。

  1. 前半(クリップ):ベジエクリッピング法とまったく同じ手順で、 凸包性による棄却とu/v交互クリップを繰り返す。
  2. UV範囲の幅が指定したしきい値(既定 0.05。三角形化法の分割幅と同程度)を 下回った時点で、「この範囲内には交点が必ず1つある」とみなし、 ニュートン法に切替える
  3. 後半(ニュートン):範囲の中心 (u, v) を初期値として、 連立方程式 g₁(u,v)=0, g₂(u,v)=0 を直接解く。三角形化法のような画面投影を介さず、 曲面の偏微分 Su, Sv を使った解析的ヤコビアンで解くため、 有限差分より高速かつ高精度。
J = [ n₁・Sᵤ  n₁・Sv ;  n₂・Sᵤ  n₂・Sv ]  (解析的ヤコビアン)
[Δu, Δv]ᵀ = J⁻¹ ・ ( −g₁, −g₂ )ᵀ
(u, v) ← (u, v) + (Δu, Δv)  を数回(通常3〜4回)繰り返す

クリップ側は「解の存在範囲をロバストに絞り込む」役、ニュートン側は 「絞り込んだ範囲を高速に仕上げる」役、と分業させることで、 クリップ単独より反復回数が減り、かつ三角形化法のようなメッシュ生成コストも要らない。

③ クリップで絞り込み、しきい値以下でニュートン法に切替 反復 UV幅 切替しきい値 (例 0.05) クリップ(線形収束) ニュートン法(2次収束) 数回で誤差が急減
図3 — 横軸は反復回数、縦軸はUV範囲の幅(模式図)。前半のクリップは緩やかに(線形に)収縮するが、しきい値を境にニュートン法へ切替えると誤差が急速に潰れる。

長所

  • クリップ単独より反復回数(=計算時間)を削減できる。終盤の遅い線形収束区間を ニュートン法の2次収束に置き換えるため
  • メッシュ生成が不要なぶん、三角形化法よりさらに高速
  • 切替前のクリップで「解が存在する範囲」を確定してからニュートン法に入るため、 初期値が悪くて発散するリスクが小さい
  • 複数交点(4分割フォールバック)にもクリップ側の仕組みがそのまま使える

短所

  • 切替しきい値の選び方に依存する:大きすぎるとニュートン法の初期値が 悪くなり収束が乱れ、小さすぎるとクリップの反復が減らずメリットが薄れる
  • 実装は三者の中で最も複雑(クリップとニュートンの両方のコードが要る)
  • ごく稀な接線的交差では、ニュートン法が収束せずクリップ範囲の中心値に フォールバックすることがある

実測比較(本アプリのティーポット例)

同じクリック位置に対して三手法を切り替えて実行し、 performance.now() で計測した例:

④ ティーポット例の計算時間(実測・単位 ms、値が小さいほど速い) 三角形化+ニュートン法 4.300 ms ベジエクリッピング法 0.500 ms ハイブリッド法 0.300 ms 0
図4 — 同一クリックでの3手法の計算時間。三角形化法はメッシュ生成コストが常に一定額かかるのに対し、クリップ系の2手法は凸包性による即時棄却が効くぶん大幅に速い。
手法計算時間三角形化比
三角形化+ニュートン法4.300 ms基準(1.0倍)
ベジエクリッピング法0.500 ms約 8.6倍速い
ハイブリッド法0.300 ms約 14倍速い

このティーポットの例では、ベジエクリッピング法は三角形化法よりすでに速く、 ハイブリッド法はさらにその上をいく(三角形化法に対して実測でおよそ10倍以上、 この例では約14倍)。差が生まれる主因は次の2つである。

実際の比率は曲面の形状・パッチ数・クリック位置(レイがどれだけ多くのパッチと 交差するか)によって変動する。本アプリのサイドバーでは同じクリックに対して 手法を切り替えて何度でも実測できるので、形状を変えながら傾向を確かめてみてほしい。

比較表

観点三角形化+ニュートン法ベジエクリッピング法ハイブリッド法
初期解の求め方N×N分割メッシュへの点in三角形判定+重心座標補間制御係数の凸包性による棄却/包絡線クリップクリップで絞り込んだ範囲の中心
終盤の収束速度2次収束(ニュートン法)線形収束(クリップのみ)2次収束(クリップ→ニュートン切替)
精度の保証局所収束のみ(初期値依存)凸包性に基づく厳密な範囲追跡クリップの保証+ニュートンの速さ
取りこぼし(偽陰性)メッシュ分割が粗いと起こりうる理論上は起こらない理論上は起こらない(前半はクリップと同じ)
前処理コスト曲面ごとに固定のメッシュ生成が必ず必要パッチ全体を1回判定するだけで大半を即棄却できるベジエクリッピング法と同じ
複数交点への対応三角形ごとに独立に検出収束が遅い領域のみ4分割して追跡クリップ側の4分割をそのまま利用
実装の複雑さ低い中〜高最も高い(両方のコードが必要)
実測(ティーポット例)4.300 ms0.500 ms0.300 ms

三手法とも最終的に得られる (u, v) の精度は同程度まで詰められるが、 速さの序列はほぼ一貫してハイブリッド法 < ベジエクリッピング法 < 三角形化法 (ハイブリッド法が最速)になる。三角形化法が常に固定コストのメッシュ生成を 背負うのに対し、クリップ系の2手法は凸包性による即時棄却で大半のパッチを 無視できるぶん有利であり、さらにハイブリッド法は終盤の遅い線形収束を 2次収束のニュートン法に置き換えることで、クリップ単独よりも一段速くなる。

実際の計算時間はパッチ数・曲率・クリック位置などに依存するため、 本アプリのサイドバーでは同じクリック位置に対して三手法を切り替えて実行し、 それぞれの計算時間を performance.now() で計測・比較できるようにしてある。 形状やクリック位置を変えながら実測比較してみるのが最も確実である。