绕点旋转很简单:绕点旋转的一步仿射变换?
但是,我遇到了一个问题:之前旋转“轨道物体”时它不起作用。这是代码:
import UIKit
class ViewController: UIViewController {
var orbitingImageView: UIImageView!
var centerImageView: UIImageView!
let rr: CGFloat = .pi / 4
override func viewDidLoad() {
super.viewDidLoad()
centerImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 150, height: 150))
centerImageView.center = CGPoint(x: 300, y: 400)
centerImageView.backgroundColor = .red
view.addSubview(centerImageView)
orbitingImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
orbitingImageView.center = CGPoint(x: 500, y: 400)
orbitingImageView.backgroundColor = .blue
view.addSubview(orbitingImageView)
orbitingImageView.transform = orbitingImageView.transform
.rotated(by: rr) //without it works fine
n()
}
func n() {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) { //little trick to make an animation
let angle: CGFloat = 0.05
let orb = self.orbitingImageView!
let cen = self.centerImageView!
let a = CGPoint(x: cen.center.x - orb.center.x,
y: cen.center.y - orb.center.y)
self.orbitingImageView.transform = self.orbitingImageView.transform
.translatedBy(x: a.x, y: a.y)
.rotated(by: angle)
.translatedBy(x: -a.x, y: -a.y)
self.n()
}
}
}
extension CGAffineTransform { //helper methods
func getScale() -> CGFloat {
return (self.a * self.a + self.c * self.c).squareRoot()
}
func getRotation() -> CGFloat {
return atan2(self.b, self.a)
}
}
现在,我可以像这样修改 n() 函数:
func n() {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) { //little trick to make an animation
let angle: CGFloat = 0.05
let orb = self.orbitingImageView!
let cen = self.centerImageView!
let a = CGPoint(x: cen.center.x - orb.center.x,
y: cen.center.y - orb.center.y)
self.orbitingImageView.transform = self.orbitingImageView.transform
.rotated(by: -self.rr)
.translatedBy(x: a.x, y: a.y)
.rotated(by: angle)
.translatedBy(x: -a.x, y: -a.y)
.rotated(by: self.rr)
self.n()
}
}
它再次起作用。但是,这种方法需要存储初始角度(变量 rr)。
我如何计算rr?
这只是我在“真实”项目中使用的代码的简化版本。在那里我可以平移/捏/旋转屏幕上的多个对象。例如,如果我选择了 2 个对象,第一个对象(我的手指在其上)应该围绕其中心旋转,而第二个应该围绕第一个点的中心旋转。然后就是这个问题,因为如果第二个对象之前单独旋转(通过它的中心),我需要这个旋转(这里是 rr )。
最后,我找到了解决方案。我没有计算 rr,而是用 1 步法替换了围绕点的 3 步旋转:
let tr = CGAffineTransform(
a: cos(angle),
b: sin(angle),
c: -sin(angle),
d: cos(angle),
tx: a.x - a.x * cos(angle) + a.y * sin(angle),
ty: a.y - a.x * sin(angle) - a.y * cos(angle)
)
self.orbitingImageView.transform = self.orbitingImageView.transform
.concatenating(tr)
全码:
import UIKit
class ViewController: UIViewController {
var orbitingImageView: UIImageView!
var centerImageView: UIImageView!
let rr: CGFloat = .pi / 4
override func viewDidLoad() {
super.viewDidLoad()
centerImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 150, height: 150))
centerImageView.center = CGPoint(x: 300, y: 400)
centerImageView.backgroundColor = .red
view.addSubview(centerImageView)
orbitingImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
orbitingImageView.center = CGPoint(x: 500, y: 400)
orbitingImageView.backgroundColor = .blue
view.addSubview(orbitingImageView)
orbitingImageView.transform = orbitingImageView.transform
.rotated(by: rr)
.scaledBy(x: 0.5, y: 0.5) //even works with prescaling
n()
}
func n() {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
let angle: CGFloat = 0.05
let orb = self.orbitingImageView!
let cen = self.centerImageView!
let a = CGPoint(x: cen.center.x - orb.center.x,
y: cen.center.y - orb.center.y)
let tr = CGAffineTransform(
a: cos(angle),
b: sin(angle),
c: -sin(angle),
d: cos(angle),
tx: a.x - a.x * cos(angle) + a.y * sin(angle),
ty: a.y - a.x * sin(angle) - a.y * cos(angle)
)
self.orbitingImageView.transform = self.orbitingImageView.transform
.concatenating(tr)
self.n()
}
}
}
现在它适用于预旋转以及预缩放。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句