Swift3で座標から角度を得る方法


画面をタップしたままドラッグすると現在自分がドラッグしてる座標の角度を割り出せるようにしてみます。時計をクルクル回したり、車のハンドルを回したり、金庫の鍵を回したりするのに使えそうです。

xとyを保持しておくstructを定義する

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))
    }

ドラッグ時に呼ばれるメソッド

    // ドラッグ時に呼ばれる
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        //タッチイベントを感知
        let touchEvent = touches.first!
        //ドラッグ前の座標
        let preDx = touchEvent.previousLocation(in: self.view).x
        let preDy = touchEvent.previousLocation(in: self.view).y
        //ドラッグ後の座標
        let newDx = touchEvent.location(in: self.view).x
        let newDy = touchEvent.location(in: self.view).y

        //ドラッグ後の座標からドラッグ前の座標を引けば現在の座標の位置が割り出せる
        let dx = newDx - preDx
        let dy = newDy - preDy

        //引数に現在の座標を入れてさっきの関数を呼ぶ
        print(angle(a: Point(x: 0, y: 0), b: Point(x: Double(dx), y: Double(dy))))
    }

全ソース

import UIKit

class ViewController: UIViewController {


    override func viewDidLoad() {
        super.viewDidLoad()

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    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))
    }

    // ドラッグ時に呼ばれる
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

        let touchEvent = touches.first!
        let preDx = touchEvent.previousLocation(in: self.view).x
        let preDy = touchEvent.previousLocation(in: self.view).y

        let newDx = touchEvent.location(in: self.view).x
        let newDy = touchEvent.location(in: self.view).y

        let dx = newDx - preDx
        let dy = newDy - preDy

        print(angle(a: Point(x: 0, y: 0), b: Point(x: Double(dx), y: Double(dy))))


    }

}

参考

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

藤沢瞭介(Ryosuke Hujisawa)
  • りょすけと申します。18歳からプログラミングをはじめ、今はフロントエンドでReactを書いたり、AIの勉強を頑張っています。off.tokyoでは、ハイテクやガジェット、それからプログラミングに関する情報まで、エンジニアに役立つ情報を日々発信しています!

未整理記事