n番煎じであっても自分でメモすることが…大事…!

Cubic Hermite Spline

いわゆるエルミート曲線

3次式
\(y(t) = a t^3 + b t^2 + c t + d\)
とその導関数
\(y′(t) = 3 a t^2 + 2 b t + c\)
を考え,

2つの端点\(t_0\), \(t_1\)で以下の4つの条件を満たすような係数\(a,b,c,d\)を求める.
\(y(t_0) = y_0\)
\(y(t_1) = y_1\)
\(y'(t_0) = d_0\)
\(y'(t_1) = d_1\)

4つの未知数と4つの方程式なので解ける.
\(a = 2 y_0 - 2 y_1 + d_0 + d_1\)
\(b = -3 y_0 + 3 y_1 - 2 d_0 - d_1\)
\(c = d_0\)
\(d = y_0\)

係数\(a,b,c,d\)による元の3次式は, 端点を通り且つ端点での接線が条件に一致するような曲線になる→ Cubic Hermite Curve
\(y(t) = (2 y_0 - 2 y_1 + d_0 + d_1) t^3 + (-3 y_0 + 3 y_1 - 2 d_0 - d_1) t^2 + d_0 t + y_0\)

バリエーションによっては接線ではなく更に外側の2点を利用するものがある.

また, 元の関数の定義域xを正規化された定義域t [0,1]へ変換して利用する場合には, x->tの変換によって接線の勾配が変化するため考慮する必要がある.
\(y(x) , x_0 <= x <= x_1\)
\(t = x / (x_1 - x_0)\)
\(dt = dx/(x_1 - x_0)\)
\(dy/dx = dy/(dt * (x_1 - x_0))\)
\(dy/dt = (x_1 - x_0) * dy/dx\)

auto CubicHermite = [](float t, float y0, float y1, float d0, float d1)
{
	constexpr auto k_a = 2.0 * y0 - 2.0 * y1 + d0 + d1;
	constexpr auto k_b = -3.0 * y0 + 3.0 * y1 - 2.0 * d0 - d1;
	constexpr auto k_c = d0;
	constexpr auto k_d = y0;
<span class="synStatement">return</span> k_a*(t*t*t) + k_b*(t*t) + k_c*(t) + k_d;

};

constexpr auto y0 = 0.0f; constexpr auto y1 = 1.0f; constexpr auto d0 = 1.0f; constexpr auto d1 = 1.0f;

constexpr auto hv0 = CubicHermite(0.0f, y0, y1, d0 ,d1); // 0.0 constexpr auto hv1 = CubicHermite(0.5f, y0, y1, d0 ,d1); // 0.5 constexpr auto hv2 = CubicHermite(0.8f, y0, y1, d0 ,d1); // 0.8 constexpr auto hv3 = CubicHermite(1.0f, y0, y1, d0 ,d1); // 1.0

Catmull-rom Spline

連続する点について隣接する4点から評価されるCubic Hermite Splineを接続した曲線シーケンス.
接続部で一階の導関数が連続.

B-Spline


元のはてなブログ記事