Translate

pythonで座標データから角度を求める方法(アークコサインを使った方法)

以前ブログ記事で、座標データからアークタンジェントを使った角度計算方法について紹介しました。

この方法はかなり直感的でわかりやすい反面、アークタンジェントから角度を算出する性質上、データの符号がいきなり飛んだりすることもあり、狭い範囲の角度データの計算の場合には、ちょっと使いにくい所がありました。

今回紹介するpythonのnumpyを使った角度計算では、アークタンジェントではなく、アークコサインとベクトルの内積を使います(うまくできているかはわかりませんが。。。(;^ω^))。

python超絶初心者の甘味が理解した内容をそのまま垂れ流して書いているので間違いとかあったらごめんなさい。


アークコサインを使った角度計算の方法



アークコサインを使った方法では、使いたい座標の二点間の座標の差分データから三角関数を使って計算します。使うデータのイメージ図は具体的にはこんな感じ。


後はオフセット軸になるベクトルを設定(1,0)して、これら二つのベクトルの内積からコサイン求めて、アークコサインを使ってラジアンを算出、最終的にラジアンから角度に変換という処理過程になります。これらを具体的にnumpyを使ってpythonの関数で書いてみるとこんな感じになります。

import numpy as np 
import math
from numpy import linalg as LA
d_vec =np.array([1,0]).reshape(1,-1)
def calangle(data1,d_vec):

    Ang = np.zeros([len(data)])    
    for t in range(0,len(data)):
        d = data[t,:]
        n_d = LA.norm(d)
        dot =np.dot(d_vec,d)/n_d
        acos = np.arccos(dot)
        Ang[t] = math.degrees(acos)
    return Ang
    

内積の計算はpythonのnumpyパッケージに入っていて、np.dot()がそれに該当します。今回の関数は、既に差分計算をしてある一次元配列(data)を想定しています。内積からアークコサインを求めるには、内積をノルム積というのもので割るらしいです(ノルム積は数学苦手でよくわからん(;^ω^))。

ノルム積に関しても内積と同じくpythonのnumpyで実装されております。numpyのlinalgの中に入っているみたいですね。そこから.norm()を呼び出してノルム積を計算、そして割り算という流れ。

内積から得られたコサインを今度は逆関数をかけて、ラジアンに変更します。その処理には、np.arccos()を使用します。これによりラジアンが計算されるのですが、ラジアンだと直感的に角度がわからないので、math関数を使って角度に変換します(math.degree())。

この一連の処理を、元データの一行目から順番にループ回路で処理していき、一行毎に逐次計算された計算結果があらかじめ用意しておいた空配列Angに蓄積されていくといった感じになります。


数学苦手だととっつきにくいですが、処理過程を描いてみると結構簡単にかけるものですね。0~180の角度の範囲内に収まる場合の計算の場合には、アークタンジェントよりもアークコサインの方がいいのかもしれませんね。

逆に180°を超える回転をする場合には、アークタンジェントの方がうまく計算できる印象です(符号が入れ変わった所とかでif関数とか使って場合分けしたりと処理が若干面倒くさくなりますが、定数の角度を足したり引いたりするだけなので、処理自体はそこまで難しくないはず。。。)。

やはりベクトルとか行列を扱う上では、numpyは最高に扱いやすいです。