ios swift 图形的旋转 atan2 函数

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

   

由于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 UIKit

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

 

 

我的Github地址:https://github.com/klbest1/MyIOSDemo,记得点赞额

 

 

哈哈,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值