ひとことで
Non-Uniform Rational B-Spline の略で、B スプラインの各制御点に重みを持たせ、ノット間隔も自由(非一様)にした曲線です。重みを使った有理式にすることで、多項式では表せない円・楕円・円弧を誤差ゼロで表現できます。CAD や 3D モデリングツールの標準的な曲線・曲面表現です。
ゲームでの使いどころ
- 正確な円軌道:衛星、回転する砲台の射程、円形のアリーナの縁など、半径がずれると困る軌道。
- CAD データの取り込み:工業製品や建築データは NURBS 曲面で作られていることが多く、ゲームに取り込む際にテッセレーション(三角形化)します。
- エディタツール:直線・円弧・自由曲線を 1 つの表現で扱えるため、道路やレールの設計ツールの内部表現に使われます。
- 重みによる局所的な引き寄せ:特定の制御点だけ曲線を強く引き寄せたいとき、位置を動かさずに重みで調整できます。
しくみ
各制御点 に重み を与え、重み付き平均を取ります。
分母があるので「有理(rational)」と呼びます。計算上は、点を同次座標 に持ち上げて普通の B スプラインとして評価し、最後に で割るだけです。
円が正確に描ける理由は、円錐曲線(円・楕円・放物線・双曲線)が 2 次の有理式で表せるからです。4 分の 1 円は、角の制御点の重みを
にした 2 次の有理ベジェで表せます。デモの円は、この 4 分の 1 円を 4 つつないだ 9 点のクランプ NURBS です。
- :その制御点に引き寄せられ、角ばった形(双曲線寄り)になる
- :通常の B スプライン(放物線)
- :制御点の影響が弱まり、内側へしぼむ(楕円寄り)
実装のポイント
- three.js にもある:
three/addons/curves/NURBSCurve.jsとNURBSSurface.jsで評価できます。 - ゲーム内ではテッセレーションして使う:実行時に NURBS を直接評価するより、読み込み時にポリラインやメッシュへ変換するのが一般的です。
- 重みは正の値に:0 や負の重みは分母が 0 になる箇所を生み、曲線が無限遠に飛びます。
つまずきやすい点
- パラメータが等速にならない:正確な円でも、 に対して角度は一定の速さで進みません(中央が速い)。等速で回したいなら弧長パラメータ化か、円なら角度を直接使います。
- 扱いが複雑:ノット列、次数、重みの 3 つを正しく管理する必要があります。単に滑らかな経路が欲しいだけなら、ベジェやカトマル・ロムで十分なことがほとんどです。
- 非一様ノットの意味:ノット間隔を変えると、区間ごとのパラメータの割り当てが変わり、形と速度分布の両方に影響します。
デモで試すこと
- 初期値の では、青い曲線と灰色の真円が完全に重なり、「真円からの最大ずれ」が 0.0000 になります。
- スライダーで重みを 1.6 程度まで上げると、曲線が角の制御点(黄色)に引き寄せられ、四角に近づきます。赤い線は真円とのずれです。
- 重みを 0.3 程度まで下げると、曲線は内側へしぼみます。最後に「w = √2/2 に戻す」を押してください。