首先要理解 反正切函数,上图来解释:
由于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,记得点赞额
哈哈,