![見出し画像](https://assets.st-note.com/production/uploads/images/99746495/rectangle_large_type_2_45d255fff48a0c11b7cfaba49f45987e.png?width=1200)
Rを使って3点の座標から角度を求める
はじめに
3地点の座標データから角度を求めるにはどうすれば…
— k.kwmt (@irabudondokodon) March 7, 2023
この頃、もっと勉強しとけば良かったと後悔しかない。#R
すぐに回答できなかったので数学の復習も兼ねて調べてみました。
基本的な考え方
角度は2つのベクトルの内積を計算することで求めることができるらしいです。
ここまでを全てまとめると、最終的に公式は次のようになります。
角度θ = arccosine((v1 • v2) / (|v1| |v2|))
(中略)
グラフィックプログラマーの仕事は、ベクトルの長さではなく、たいていはその方向だけを重要視します。次の手順で方程式を簡単にして、プログラムの速度を上げましょう。[6] [7]
それぞれのベクトルを正規化し、長さを1にしましょう。正規化するため、それぞれの成分をベクトルの長さで割りましょう。
もともとのベクトルの代わりに、正規化したベクトルの内積を利用しましょう。
長さが1であるため、方程式で長さの条件を考慮に入れる必要はありません。最終的に角度を求める方程式は次のようになります。θ=arccos(v1 • v2)
データ
#座標の指定
o <- c(1,1)
a <- c(3,3)
b <- c(1,4)
#一応可視化
tibble(x = c(1,3,1), y = c(1,3,4), label = c("o", "a", "b")) %>%
ggplot() +
theme_classic(base_size = 20) +
geom_point(aes(x=x,y=y), size = 5) +
geom_text(aes(x=x,y=y,label=label), nudge_x = -.3, nudge_y = .3, size = 10) +
geom_segment(aes(x = 1, y = 1, xend = 1, yend = 4)) +
geom_segment(aes(x = 1, y = 1, xend = 3, yend = 3)) +
xlim(c(0,5)) +
ylim(c(0,5)) +
coord_fixed()+
labs(x = "", y = "")
![](https://assets.st-note.com/img/1678235932021-1bY4HqJDeM.png?width=1200)
計算
ベクトルを作る
#点oを基準にベクトルを作る
v1 <- a - o #(2,2)
v2 <- b - o #(0,3)
ベクトルの長さを1にする(標準化)
v1 <- v1/sqrt(sum(v1^2))
v2 <- v2/sqrt(sum(v2^2))
ベクトルの長さは√x^2 +y^2で計算します。
各ベクトルを長さで割ることで標準化できます
角度を求める
acos(v1 %*% v2)*180/pi
標準化されたベクトルの内積はcosθとなります。
内積の求め方は2つあります
sum(v1*v2)
v1 %*% v2
わからない場合はv1*v2をしてみてください。その結果を足したものが内積です。
cosθからθを求めるにはarccosineを使います。rではacos()を使います。
acos(v1 %*% v2)
この結果のθの単位はラジアンです。これを°に直すには180をかけてπで割ります。
πはrではpiと表記します。
#試しにπを出してみる
pi
#θに180かけてπで割る
acos(v1 %*% v2)*180/pi
終わりに
数式で書くと一瞬わかりにくいことでも1つずつ確認すると勉強になりますね。ググり力も大事なんですが、実は最初にChatGPTで確認してみました。
![](https://assets.st-note.com/img/1678241164361-RbYyXA9sbl.png?width=1200)
あってるのか心配なのと、ちゃんと自分で理解するためにコードを書き直したのが上記になります。他にも回答方法はいくつもあると思いますので、練習がてら挑戦してみてはいかがでしょうか。