MATLAB解析の解説では、関節角度を1行で計算しました: atan2d(det(v1, v2), dot(v1, v2))。動きはしますが、なぜこれが2つの体節ベクトルのなす角になるのでしょうか。本記事はその1行の背後にある数学と、なぜ2引数の atan2 が正しい道具なのかを解説します。
準備: 関節から出る2つのベクトル
膝の角度を考えます。膝から2つのベクトルを引きます: 足首へ(下腿)と股関節へ(大腿)。関節角度は、この2つのベクトルのなす角 θ です。

行列式 = 外積の大きさ = 面積
2つの2Dベクトルについて、行列式は2ベクトルが張る平行四辺形の面積に等しく、それはまさに外積の大きさです。そして外積の大きさは |v1|·|v2|·sin(θ) です。

なぜ外積関数ではなく det を使うのか。MATLAB の cross は3Dベクトル(X, Y, Z)を必要とし、姿勢データは2Dだからです。2つの2Dベクトルの行列式なら、Zを足さずに同じ値が得られます。デモでは4になり、外積の大きさと一致します。
内積 = 射影
同じ2ベクトルの内積は |v1|·|v2|·cos(θ)——幾何学的には一方を他方へ射影したものです。デモでは2になります。
まとめると: tan(θ)
外積を内積で割ります:
- 外積 =
|v1|·|v2|·sin(θ) - 内積 =
|v1|·|v2|·cos(θ) - 外積 / 内積 =
sin(θ) / cos(θ) = tan(θ)
大きさが打ち消し合い、tan(θ) が残ります。よって θ = atan2(det, dot)。デモでは外積=4、内積=2 で、式は −63.4° を返し、直接測った角度と一致します。

なぜ atan2 で、ただの atan ではないのか
1引数の atan は比だけを取るため、符号の情報を捨ててしまいます: (−, +) と (+, −) はどちらも負に、(+, +) と (−, −) はどちらも正に見えます。どの象限かを判別できず、90°を超える角度で破綻します。例えば実際には 153° の股関節角度は、atan2d なら正しく153°を返しますが、ただの atan は 26° を返します——if 文で(180° − 角度)と補正する必要が出ます。
2引数の atan2(分子, 分母) は分子と分母を分けて渡すため、全範囲を解決し符号も保ちます。バイオメカニクスではこの符号に意味があります: 股関節ではバックスイングが負、フォワードスイングが正になり、角度の符号だけで両者を見分けられます。
まとめ
この1行 atan2d(det, dot) は、シンプルかつ堅牢なことをしています: 行列式から角度のサイン、内積からコサインを読み取り、符号と 0–180°(およびそれ以上)の全範囲を保つように組み合わせるのです。だからこそ、2Dの関節角度を計算する信頼できる方法なのです——そのまま解析パイプラインに組み込めます。
著者について
Takashi Fukushima — スポーツ・運動科学 × Human Pose Estimation × Computer Vision × XR を横断して研究・開発しています。
- YouTube(登録): Takashi Fukushima|Sports Science & Pose Estimation
- 研究(ORCID): orcid.org/0000-0002-7318-3384
- ウェブサイト: takashifukushima.com
- お問い合わせ: お問い合わせフォーム