とある Python プログラムのお披露目のサイトで,「三次元空間における2つのベクトルのなす角度の計算」があった。
パッケージの関数を使いまくりで,わかりやすいのかわかりにくいのか。
import numpy as np
def angle(a, b, c):
# ベクトルを定義
vec_a = a - b
vec_c = c - b
# コサインの計算
length_vec_a = np.linalg.norm(vec_a)
length_vec_c = np.linalg.norm(vec_c)
inner_product = np.inner(vec_a, vec_c)
cos = inner_product / (length_vec_a * length_vec_c)
# 角度(ラジアン)の計算
rad = np.arccos(cos)
# 弧度法から度数法(rad ➔ 度)への変換
degree = np.rad2deg(rad)
return rad, degree
http://w3e.kanazawa-it.ac.jp/math/category/vector/henkan-tex.cgi?target=/math/category/vector/naiseki-wo-fukumu-kihonsiki.html
にあるように,式自体は簡単なのと,numpy.ndarray は要素ごとの演算ができるのが特徴なので,以下のように簡単になる。
内積: sum(x * y)
ノルム:np.sqrt(sum(x**2))
ノルム:np.sqrt(sum(y**2))
長すぎる変数名というのも,読みにくいなあ。
def angle2(a, b, c):
x = a - b
y = c - b
cos_theta = sum(x * y) / np.sqrt(sum(x**2)) / np.sqrt(sum(y**2))
rad = np.arccos(cos_theta)
degree = rad * 180 / np.pi
return rad, degree
>>> a = np.array([0, 1, 2])
>>> b = np.array([10, 20, 30])
>>> c = np.array([5, 7, 9])
>>> print(angle(a, b, c)) # (0.09657114452339467, 5.533119003938428)
>>> print(angle2(a, b, c)) # (0.09657114452339467, 5.533119003938429)
>>> a = np.array([2.123, 3.215, 4.325])
>>> b = np.array([1.547, 2.487, 6.543])
>>> c = np.array([3.234, 1.124, 4.328])
>>> print(angle(a, b, c)) # (0.8548133509459923, 48.97719728064064)
>>> print(angle2(a, b, c)) # (0.8548133509459923, 48.97719728064063)
※コメント投稿者のブログIDはブログ作成者のみに通知されます