Posted at

2つの座標から角度や距離を求める

More than 3 years have passed since last update.


はじめに

この記事は、岩手県立大学アドベントカレンダー2015 19日目の記事です。

今回は、平面上に2つの座標を与えられたときの2つの座標からなる角度や距離を求めます。

Swiftでの記述例を示しますが、他のプログラミング言語でも同様の方法で求めることができます。

以下の画像を参考にします。


角度を求める

原点O(0, 0)と点(5, 5)からなる角度は45度です。

逆正弦atan2(アークタンジェント2)を使います。

atan2は点(x, y)とx軸によって表されるベクトルの角度(θ)を返します。

よって位置から角度を求めることができます。


sample1.swift

struct Point {

var x:Double = 0
var y:Double = 0
}

func angle(a:Point, b:Point) -> Double {
var r = atan2(b.y - a.y, b.x - a.x)
if r < 0 {
r = r + 2 * M_PI
}
return floor(r * 360 / (2 * M_PI))
}

print(angle(Point(x: 0, y: 0), b: Point(x: 5, y: 5))) // 45.0
print(angle(Point(x: 0, y: 0), b: Point(x: 0, y: 10))) // 90.0
print(angle(Point(x: 0, y: 0), b: Point(x: -10, y: -10))) // 225.0



距離を求める

距離は三平方の定理で求めることができます。

原点O(0, 0)と点(0, 10)の距離は10です。

原点O(0, 0)と点(5, 5)の距離は

1:1:\sqrt{2}

の三角形より5*1.4142=7.07106781187となります。


sample2.swift

struct Point {

var x:Double = 0
var y:Double = 0
}

func distance(a:Point, b:Point) -> Double {
return sqrt(pow(b.x - a.x, 2) + pow(b.y - a.y, 2))
}

print(distance(Point(x: 0, y: 0), b: Point(x: 5, y: 5))) // 7.071
print(distance(Point(x: 0, y: 0), b: Point(x: 0, y: 10))) // 10.0
print(distance(Point(x: 0, y: 0), b: Point(x: -10, y: -10))) // 14.142



方向を求める

始点と終点の座標から方向を求めます。

方向は下記の図のように8種類あるものとして、その番号を返します。

スワイプの方向を求めることができます。


sample3.swift

struct Point {

var x:Double = 0
var y:Double = 0
}

func direction(angle: Double) -> Int {
if(23 <= angle && angle <= 67) {
return 7;
}else if(68 <= angle && angle <= 112) {
return 6;
}else if(113 <= angle && angle <= 157) {
return 5;
}else if(158 <= angle && angle <= 202) {
return 4;
}else if(203 <= angle && angle <= 247) {
return 3;
}else if(248 <= angle && angle <= 292) {
return 2;
}else if(293 <= angle && angle <= 337) {
return 1;
}else {
return 0;
}
}

print(direction(angle(Point(x: 0, y: 0), b: Point(x: 5, y: 5)))) // 7
print(direction(angle(Point(x: 0, y: 0), b: Point(x: 0, y: 10)))) // 6
print(direction(angle(Point(x: 0, y: 0), b: Point(x: -10, y: -10)))) // 3



おわりに

明日は20日目 @yuzumone さんです。