エルミート曲線

公開 更新

エルミート曲線は3次方程式を使い、位置だけでなく始点と終点の接線情報も考慮して間を補完する曲線を作ることができる。始点から始点のベクトル方向に飛び出した曲線が、終点では終点ベクトルの向きで到着する。3次方程式で表現されるため、始点からひとつめのカーブへ進み、ふたつめのカーブから終点へ進む、という形になる。

計算式

エルミート曲線のパラメータは

始点(P0) 始点の速度ベクトル(V0) 終点(P1) 終点の速度ベクトル(V1

エルミート補完ではカーブの式を3次関数として定義する。

f(t)=at3+bt2+ct+df(t) = at^3+bt^2+ct+d

f(t)f(t)は時間(t)に対する位置。tは0~1。

始点P0=f(0)=dP_0 = f(0) = d・・・①

終点P1=f(1)=a+b+c+dP_1 = f(1) = a + b + c +d・・・②

式を微分すると、

f(t)=3at2+2bt+cf'(t) = 3at^2+2bt+c

f(t)f'(t)は速度の関数(時間tに対する変化率)となる。(スカラー値ではなくベクトル)

始点のベクトルV0=f(0)=cV_0 = f'(0) = c・・・③

終点のベクトルV1=f(1)=3a+2b+cV_1 = f'(1) = 3a+2b+c・・・④

①と③を②に代入すると

P1=a+b+P0+V0P_1 = a + b + P_0 + V_0

③を④に代入すると

V1=3a+2b+V0V_1 = 3a + 2b + V_0

a, bについて解くと

a=2(P0P1)+V0+V1a = -2(P_0 - P_1) + V_0 + V_1

b=3(P1P0)2V0V1b = 3(P_1 - P_0) - 2V_0 - V_1

3次式f(t)=at3+bt2+ct+df(t) = at^3+bt^2+ct+dに代入していくと

c=V0c = V_0d=P0d= P_0なので

f(t)=(2(P0P1)+V0+V1)t3+(3(P1P0)2V0V1)t2+V0t+P0f(t) = (-2(P_0 - P_1) + V_0 + V_1)t^3+(3(P_1 - P_0) - 2V_0 - V_1)t^2+V_0t+P_0

となる。

コード

ポリライン2本をマージしたものをWrangleノードに差しています。

//
// エルミート曲線を描く
// Run Over: Detail
//
int pts[] = primpoints(0, 0);
int pts2[] = primpoints(0, 1);

vector p0 = point(0, "P", pts[0]);
vector p1 = point(0, "P", pts[1]);
vector p2 = point(0, "P", pts2[0]);
vector p3 = point(0, "P", pts2[1]);

vector v0 = (p1 - p0);
vector v1 = (p3 - p2);

int prim = addprim(0, "polyline");
int num = 100;
for(int i = 0; i < num; i++)
{
    float t = i / float(num-1);
    vector pos = (-2*(p2-p0)+v1+v0)*t*t*t + (3*(p2-p0)-v1-2*v0)*t*t + v0*t + p0;
    
    int pt = addpoint(0, pos);
    addvertex(0, prim, pt);
}

← 記事一覧へ