ios swift 图形的旋转 atan2 函数

来源:互联网 发布:编程方法学 编辑:程序博客网 时间:2024/06/01 09:13

   首先要理解 反正切函数,上图来解释:

   

由于iphone坐标系统的原因,此图y轴向下增大。

atan2(y,x) 其实求得是A点与x轴正方形的夹角。A = -2.0 rad, A' = -0.75 rad  求转过的角度 mRotate : -0.75 - (- 2.0) =   1.25 正值。 ps:(A' - A)

在x轴下方也是同样正值。

反之,逆时针旋转时,转过的角度为负值,这样刚好。


但是有一点需要注意: 当经过+PI 到-Pi的区域时,用B‘-B会是这样: -0.75PI - 0.75PI = -1.5PI 这样的值是不正确的。

于是我们需要判断顺时针旋转时,转过的角度应该是: ( B'- (-PI) )  + ( PI - B)  =  (-0.75PI - (-PI))  + (PI - 0.75PI) 这样的值才是正值。

反之逆时针旋转时:(B' - PI)+ (PI-B) = (0.75PI -PI) + (-PI - 0.75PI)  为负值

分析之后,我们再来看代码:

////  ViewController.swift//  ImageRoate////  Created by lin kang on 17/1/28.//  Copyright © 2017年 . All rights reserved.//import UIKitclass ViewController: UIViewController {    @IBOutlet weak var imageView: UIImageView!    var oldRadius:CGFloat = 0    var rotateRadius:CGFloat = 0        override func viewDidLoad() {        super.viewDidLoad()        // Do any additional setup after loading the view, typically from a nib.        let guester = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:)));        self.view.addGestureRecognizer(guester);    }    override func didReceiveMemoryWarning() {        super.didReceiveMemoryWarning()        // Dispose of any resources that can be recreated.    }    func handlePan(_ panguester:UIPanGestureRecognizer) {       let touchPoint:CGPoint = panguester.location(in: self.view)        let centerPoint:CGPoint = self.imageView.center;        let state = panguester.state;        switch state {        case .began:            let yDistance = touchPoint.y - centerPoint.y;            let xDistance = touchPoint.x - centerPoint.x            let radious =  atan2(yDistance, xDistance)            oldRadius = radious            print("start: yDistance:\(yDistance)/xDistance:\(xDistance) = \(radious)")            break        case .changed:            let yDistance = touchPoint.y - centerPoint.y;            let xDistance = touchPoint.x - centerPoint.x            let radious =  atan2(yDistance, xDistance)            var movedRadious = radious - oldRadius            //经过PI 到-PI的区域时,通过x轴来计算正确的转过的角度            if radious < CGFloat(-M_PI_2) && oldRadius > CGFloat(M_PI_2)  {                movedRadious = CGFloat((M_PI - Double(oldRadius)) + (Double(radious) + M_PI))            }else if(radious > CGFloat(M_PI_2) && oldRadius < CGFloat(-M_PI_2)){                movedRadious = CGFloat((-M_PI - Double(oldRadius)) + (Double(radious) - M_PI))            }                        rotateRadius += movedRadious;            oldRadius = radious;            print("rotateAngle:\(rotateRadius)")            self.rotateImage(angle: rotateRadius);            break        case.ended:            break;        default:            break;        }            }        func rotateImage(angle:CGFloat)  {        UIView.animate(withDuration: 0.3) {            self.imageView.transform = CGAffineTransform(rotationAngle: angle);        }    }}


哈哈,

0 0