模仿美图秀秀单指旋转图片

美图秀秀单指按住图片旋转的功能很美妙,最近为了熟悉CoreGraphics框架,模仿美图做了一些功能,因为对于放射变换不够熟悉,加上好久没有研究算法了,在单指旋转图片上还是费了一些功夫。

拖动事件

首先,先说下我用的是UIPanGestureRecognizer手势来监测拖动图片的事件的,但是并没有用gensture.translation方法来取得变化,刚开始的时候也是想用来着,后来发现我的算法根本用不上这个属性。

求每次拖动事件之间产生的夹角

因为最近也刚刚开始复习线性变换的算法,在纸上画了画旋转的过程,发现,这不就是求两个向量之间的夹角吗,哈哈哈~
好,那我们来回顾一下,向量的夹角公式

cosθ=a.b/(|a||b|)

即: θ = arccos(a和b的点乘/a的模*b的模)
两个向量a,b是从每次进入拖动事件时的location得来的,方法如下:

let currentPosition = gesture.location(in: self.bgView)
let vectorA = CGPoint(x: lastPosition.x - origin.x, y: lastPosition.y - origin.y)
let vectorB = CGPoint(x: currentPosition.x - origin.x, y: currentPosition.y - origin.y)

OK,两个向量已经准备好了,剩下的我们只要根据公式计算就可以了

// 向量a的模
let modA = sqrtf(powf(Float(vectorA.x), 2) + powf(Float(vectorA.y), 2))
// 向量b的模
let modB = sqrtf(powf(Float(vectorB.x), 2) + powf(Float(vectorB.y), 2))
// 向量a,b的点乘
let pointMuti = Float(vectorA.x * vectorB.x + vectorA.y * vectorB.y)
            
// 夹角
let angle = acos(pointMuti / (modA * modB))

向量的夹角已经计算完毕,你是不是想说,这样就做好了嘛,No,试验过程发现,不管怎样转动,图片永远向一个方向转动,What?实际上,上述公式只能求两个向量的夹角,但是,方向就没办法计算了,So,How? 请看下文。。。。

旋转方向

大学学习线性变换的时候应该有学过叉乘吧,当时你一定在想,这玩意有个卵用,对,它就是那个可以算出旋转方向的卵玩意。
百科上的解释如下:

a向量与b向量的向量积的方向与这两个向量所在平面垂直,且遵守右手定则。(一个简单的确定满足“右手定则”的结果向量的方向的方法是这样的:若坐标系是满足右手定则的,当右手的四指从a以不超过180度的转角转向b时,竖起的大拇指指向是c的方向。)

也就是说,叉乘的结果可以决定a转向b,还是b转向a。
叉乘的算法就不详细给大家描述了,贴上我的代码:

// 叉乘求旋转方向,顺时针还是逆时针
let crossAB = vectorA.x * vectorB.y - vectorA.y * vectorB.x
let sign: Float = crossAB > 0.0 ? 1.0: -1.0

目前为止,我们的旋转角度和旋转方向都已经准备好,可以旋转啦,

rotation += CGFloat(angle * sign)
self.imageView.transform = CGAffineTransform(rotationAngle: rotation)

再配上一些效果就是一个酷炫的单指旋转喽,本姑娘也是在探索中,如果有什么不对的欢迎指出,大家勿喷哦~

你可能感兴趣的:(模仿美图秀秀单指旋转图片)