Swift3で12時を起点に時計をドラッグで回転させる

以前、僕はSwift3で9時を起点に時計をドラッグで回転させるという記事を書きました。文字通り、9時を起点に時計をドラッグで回転させるというものです。なぜ9時なのか、起点を別の位置に変える方法がわかりかねたからです。実装では回転の起点をちょうど12時の場所に持って来なきゃいけなくて、僕の数学の知識がウスラトンカチだったのでかなり悩みました。

おかしくなる原因

おかしくなる原因はatan2で割り出した回転軸xとyの軸が現実世界だと中心から始まるのに対して、ウェブのの世界では左上から始まるからです。

bad.gif

考え方

考え方として、時計の針の起点が9時の部分にあったとして、それを12時の部分に持ってきたいのだから-90すればいいんじゃないかと思った訳ですが、単純に90引き算してもおかしな挙動をします。atan2で求めた角度は度数法ではなくラジアンなので、90を引くのにもラジアンで引かなければいけないってことでした。頭が悪いと苦労します…orz

good.gif

ポイント

atan2で求めたangleが「ビューの中心からみたpositionの方向」であり、方向はX軸の正の方向(左上を軸とした起点)を0として左回りにラジアンで求めています。

let angle = atan2f(Float(target.y-position.y), Float(target.x-position.x)) 

この実装に度数法ではなくアラジンで-90を引き算します。M_PI2というのは円周360なので、その半分でM_PI180を2引き算します。

- Float(M_PI) / Float(2)

全実装

import UIKit

class ViewController: UIViewController {



    var myView: UIView!
    override func viewDidLoad() {
        super.viewDidLoad()
        myView = UIView(frame: CGRect(x: 0, y: 0, width: 20, height: 100))
        myView.center = self.view.center
        myView.backgroundColor = UIColor.red;
        self.view.addSubview(myView)

        myView.layer.anchorPoint = CGPoint(x: 0.5, y: 1.0)

        let box = UIView(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
        box.backgroundColor = UIColor.blue
        myView.addSubview(box)
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent!) {

        let touch = touches.first!
        if touch.view === myView.subviews[0] {
            let position = touch.location(in: self.view)
            let target = myView.center

            let angle = atan2f(Float(target.y-position.y), Float(target.x-position.x)) - Float(M_PI) / Float(2)

            myView.transform = CGAffineTransform(rotationAngle: CGFloat(angle))
        }
}

}

参考

Swift3でタップした位置が何故か左になる
binary operator ‘/’ cannot be applied to two ‘Double’ operands
Swift3で9時を起点に時計をドラッグで回転させる

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

未整理記事