ひとことで
並べた通過点をすべて通る滑らかな曲線を、追加の制御ハンドルなしで作れるスプラインです。各点での接線を「前後の点を結ぶ向き」から自動で決めるので、配置するのは通過点だけ。カメラレール、パトロール経路、レースの走行ラインなど、「ここを通ってほしい」という指定が明確な場面の定番です。
ゲームでの使いどころ
- カメラの移動経路:カットシーンやアトラクションのように、見せたい位置を順に通るカメラワーク。デモ右上はレール上のカメラから見た映像です。
- 敵の巡回ルート:ウェイポイントを置くだけで、角で急旋回しない自然な移動経路になります。
- レースゲームのライン:AI が走るレーシングラインや、コース上のチェックポイントをつなぐ曲線。
- ネットワーク補間:過去数フレーム分の受信位置を通る曲線で、他プレイヤーの動きを滑らかに再生します。
しくみ
区間 を描くとき、前後の点 を使って両端の接線を決め、エルミート曲線として補間します。一様な場合の接線は次のとおりです。
ただし、通過点の間隔が不均一だと、一様パラメータ化では曲線が行き過ぎて尖り(カスプ)や小さなループができます。そこで、点どうしの距離に応じてパラメータの間隔を変えます。
| 名前 | 性質 | |
|---|---|---|
| 0 | 一様(uniform) | 計算が単純。間隔が偏るとループやカスプが出る |
| 0.5 | 求心(centripetal) | 区間内に自己交差やカスプが生じないことが証明されている |
| 1 | 弦長(chordal) | 大きく膨らみやすいが、曲率の変化はなだらか |
実用上は求心()が第一候補です。three.js の CatmullRomCurve3 も curveType: "centripetal" で使えます。
実装のポイント
- 始点と終点の扱い:開いた曲線では最初と最後の区間に「前後の点」がありません。端の点を複製するか、延長した仮想点を置きます。
- 注視点は別に持つ:カメラの向きを進行方向にすると、急なカーブで画面が大きく振られます。見せたい対象を別の曲線や固定点で持つと安定します(デモの「カメラの向き」)。
- 速度は弧長で:点の間隔が違うと、 を一定に進めたときの速さが区間ごとに変わります。
getPointAtのような弧長ベースの関数を使います。
つまずきやすい点
- 高さ方向の揺れ:3D の通過点の高さを少しずつ変えると、区間ごとに上下のうねりが出ます。カメラ酔いの原因になるので、高さは別に滑らかに補間するのも手です。
- 局所制御はほぼ:1 点を動かすと、その点をはさむ前後 2 区間ずつ(計 4 区間)が変わります。B スプラインほど局所的ではありませんが、実用上は十分です。
- 2 階微分は連続しない:つなぎ目で曲率が不連続になるため、非常に速い移動では加速度の変化が感じられることがあります。
デモで試すこと
- 「パラメータ化」を一様にすると、間隔の詰まった通過点 2・3 の付近に小さなループができます。求心に戻すとループが消えます。
- 通過点をドラッグしてステージの近くを通るようにすると、右上のカメラ映像が迫力のあるアングルに変わります。
- 「カメラの向き」を進行方向にすると、カーブで画面が振られる様子が分かります。