読者です 読者をやめる 読者になる 読者になる

スポーツバイオメカニクス MatlabとOpenSIM

スポーツバイオメカニクスの分析によく用いられるMatlabとOpenSIMの使用に関する備忘録

2つのベクトルのなす角

バイオメカニクスでは2つのベクトルのなす角を求めることが求められます。

例えば、関節角度です。

今回はその方法の1つである余弦定理を用いた方法を紹介したいと思います。

余弦定理とは、高校生でも知っているあの余弦定理です。

余弦定理の詳細についてはどこかのサイトを探してもらう、もしくは数学の教科書に載っています。

なので、実際の運用方法について書いていきたいと思います。

余弦定理で2つのベクトルがなす角を求めるために必要なのは、2つのベクトルの内積とそれぞれの大きさ(ノルム)です。

では、作業の方法に入ります。

まずは、座標データから2本のベクトルを作ります。

仮に、膝関節角度を求める場合は膝関節から股関節に向かうベクトルと膝関節から足関節に向かうベクトルの2本を作成します。

なので・・・

vector1=股関節-膝関節
vector2=足関節-膝関節

となります。

rowという引数の1行目から3行目に股関節のX、Y、Z座標、4行目から6行目に膝関節のX、Y、Z座標が入っているとした場合は

vector1=row(1:3,:)-row(4:6,:);

となります。

よりわかりやすくするために、

hip=row(1:3,:);
knee=row(4:6,:);

というように、わかりやすい引数にそれぞれの座標値を入れておくと次のようにより簡単に作れます。

vector1=hip-knee;

次に内積を求めます。

内積は1コマごとに求める必要があります。

したがって、1コマ目の内積

InnerProduct=dot(vector1(:,1),vector2(:,1));

で求められます。

dotは内積の関数です。

これをforを使って全コマ分求めることができます。

コマ数をFrameとしたとき、

for time=1:Frame
InnerProduct(time)=dot(vector1(:,time),vector2(:,time));
end

「for」の使い方は他のサイトを参照してもらうか、後々書きたいと思います(笑

内積が求められたら、次はそれぞれのベクトルのノルムです。

for time=1:Frame
Norm1=norm(vector1(:,time));
Norm2=norm(vector2(:,time));
end

これでノルムが全コマ分求められます。

ノルムはコマによって変わらないような気がしますが、ディジタイズ誤差によって1コマごとに変動していますので、全コマ分別に求める必要があります。

最後に余弦定理で角度を求めます。

余弦定理の式を変形すると、cosの値が得られます。

つまり、ここまでに用いてきた引数で書くと

cos=InnerProduct/(Norm1*Norm2)

になります。

これをforで全コマ分のcosの値を求めると

for time=1:Frame
cos(time)=InnerProduct(time)/(Norm1(time)*Norm2(time));
end

となります。

そして、求められたcosの値を「acos」に入れると、角度になります。

ただし、ここで算出された角度はradianなので、degree(度)に直すためには180/πをかけてやる必要があります。

したがって、膝関節の角度は・・・

angle=acos(cos)*180/pi;

で求められることになります。

いかがでしたでしょうか?

少し難しかったかもしれませんが挑戦してみてください。

なお、この方法では180度を超える角度は求められません。

180度を超える角度を求める方法はまた今度紹介したいと思います。