例子
在 iOS 旋转一张图片只需一句代码
imageView.transform = CGAffineTransformMakeRotation(β)
这句代码背后的原理是什么?
原理
我们知道图像是由很多个像素组成的(假设是1万个),那么旋转一张图像就可以理解为旋转这1万个像素,对每个像素都旋转同样的角度,那么整张图像就发生旋转了。
对1万个像素旋转同样的角度,那么只要明白对1个像素是怎么旋转的,那么来个for循环,对剩下的像素都做同样的操作就可以了。
怎么旋转一个像素
一个像素在图像中有(x, y)坐标值,看下图,像素从B点转到A点。A点到原点的距离是R,然后两个角度分别是α,β
还记得三角函数吧,旋转要用到,站在A点 (xa, ya) 的角度,可以写出下面两个三角函数式,叫式子1
xa = R * cos(α + β)
ya = R * sin(α + β)
接着用和差公式展开,得到下面的式子2,先暂时放着。
xa = R * cosα * cosβ - R * sinα * sinβ
ya = R * sinα * cosβ + R * cosα * sinβ
然后站在B点 (xb, yb) 的角度,也可以写出两个式子,叫式子3
xb = R * cosα
yb = R * sinα
上面没问题吧,接下来要发生高能反应了,观察式子2和式子3,把式子3代入到式子2中,把式子2中的 (R cosα) 替换为 xb,(R sinα) 替换为 yb,然后就得到了下面的式子4
xa = xb * cosβ - yb * sinβ
ya = yb * cosβ + xb * sinβ
大功告成,观察上式就得到了 (xb, yb) 旋转 β 角度到达 (xa, ya) 的公式了。
那么对1万个像素点都代入这公式,图像就发生旋转了,旋转动画就是 β 随着时间改变,比如把 β 从 0 增加 360 度,就旋转了一圈。
实际
上面只是原理,在实际应用中,还有一定差距,B 图像旋转到 A 图像并不是从 B 图坐标计算到 A 图坐标的,而是从 A 图向 B 图计算,逆过来的,因为按照上面的原理计算到 A 图会产生很多图像空洞,就是有像素点算不到的地方,逆过来计算,然后加上灰度插值算法(最近邻插值,双线性插值等等)最终完成旋转。
我用C++写了个图像旋转实验程序(查看)
上面复杂的计算过程iOS都帮你封装好了,最终浓缩为一句代码
imageView.transform = CGAffineTransformMakeRotation(β)