3点を通る二次関数を得る

概要

この円柱の経路は放物線を描いてます。

実際FLASH作成時に物が落下する、などの表現をする場合、座標を時間の二次関数として求めることはみなさんよくやってるかと思います。

単純に二次関数を設定できれば簡単ですが、たまに、始点、終点、適当な途中の3点を通る二次関数が欲しい、なんて場合もあります。

え?ない?いや、私はあるんです!

ということでここでは3点を通る二次関数をアクションスクリプトで求める、というのをやります。

二次関数

xy 座標の二次関数というと

 y=ax2+bx+c ・・・(1)

ってやつですね。

※お話は xy 座標で進めますが、スクリプト上のイメージとしては x が時間で y が物体の座標(xでもyでもいい)って感じですね。

この二次関数(1)上の3点をそれぞれ (x1 , y1),(x2 , y2),(x3 , y3) とします。

すると、以下の式が成り立ちます。

 y1=ax12+bx1+c ・・・(2)
 y2=ax22+bx2+c ・・・(3)
 y3=ax32+bx3+c ・・・(4)

要はこの3元の連立方程式を解いて、3つの係数 a , b , c を求めたいわけですよね。

式が3つあるから計算すれば解けるわけですが、、、

スクリプト上で使おうとあらかじめ手計算で式を求めておく、というのはやってやれないことはないでしょうが、かなり面倒。

そういうのは公文式に通う小学生達におまかせするとして、我々(って誰よ?)は先人の知恵をお借りすることにしましょう。

ガウス・ジョルダン法

ありがたいことにこういうのをサクっと求める方法があるんだそうですよ、誰が考えたんだか?

やっぱりガウス&ジョルダン?あ、でもJUDY AND MARYのボーカルはJUDYでもMARYでもなくてYUKIちゃんですから、これもわかりませんね。

ともかく、(2)〜(4)の式は行列を使って以下のように書くことができます。

y1 = x12 x1 1a
y2x22 x2 1b
y3x32 x3 1c

これが下のように変形させることができればいいわけで、というのがこの解法。

= 1 0 0a
0 1 0b
0 0 1c

アクションスクリプトだと

こちらのサイト(連立方程式の解)にあるコードを参考にさせて頂きました。

かなり基本的なものだけですが、こんな感じ。

function gaussjordan(v){
var v,a,ii,jj,kk,temp;

for (ii=0;ii<3;ii++){
a=v[ii][ii];//注目式の未知数の係数を1にするためにその係数を格納

//注目式の未知数の係数を1にするため注目式全体をaで割る
for (kk=ii;kk<4;kk++){
v[kk][ii]=v[kk][ii]/a;
}

//注目式以外の未知数の係数を0にする
for(jj=0;jj<3;jj++){
if (jj != ii){// 注目式以外なら実行する
temp=v[ii][jj];//注目式以外の未知数の係数を格納
for (kk=ii;kk<4;kk++){//その値を0にするため、注目式との演算を行う
v[kk][jj]=v[kk][jj]-temp*v[kk][ii];
}
}
}
}
return { aa:v[3][0] , bb:v[3][1] , cc:v[3][2] };
}

使うには、配列 h に必要な値を入れて、関数を呼び出しますおきます。こんな感じで。


h=[
[?,?,?],//行列の一番左の列
[?,?,?],//行列の二番目の列
[?,?,?],//行列の三番目の列
[?,?,?],//y
];
kotae=gaussjordan(h);

kotae.aa、kotae.bb、kotae.cc が解になります。

なお、解が求められない場合などの判定も行っていませんので、使用時にはご注意を。