当对象最初由其中心旋转时,围绕该点旋转对象

文章

绕点旋转很简单:绕点旋转的一步仿射变换?

但是,我遇到了一个问题:之前旋转“轨道物体”时它不起作用。这是代码:

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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

自身旋转时围绕对象的OpenGL旋转

来自分类Dev

如何围绕自己的中心旋转 SVG 对象?

来自分类Dev

PDFlib - 以任意度数围绕中心旋转对象

来自分类Dev

围绕其中心点旋转UIImageView吗?

来自分类Dev

Android动画可围绕其中心点旋转图像

来自分类Dev

Qt围绕其中心点旋转文本

来自分类Dev

鼠标移动事件后如何围绕其中心旋转Canvas对象?

来自分类Dev

围绕不断旋转的对象旋转对象

来自分类Dev

在JS中围绕旋转对象旋转对象

来自分类Dev

旋转对象时旋转

来自分类Dev

围绕位于 openGL ES 中心的对象旋转相机

来自分类Dev

如何在matlab中围绕对象中心旋转图像?

来自分类Dev

fabric.js 围绕画布中心平滑地旋转对象

来自分类Dev

SVG动画围绕其中心旋转组

来自分类Dev

LibGDX 1.5围绕其中心旋转的精灵

来自分类Dev

如何围绕其中心旋转PShape?

来自分类Dev

围绕其中心旋转绘制的文本

来自分类Dev

[AS3]围绕其中心旋转雪碧

来自分类Dev

围绕其中心旋转多边形

来自分类Dev

该Unity脚本使gameObject围绕对象旋转。怎么样?

来自分类Dev

围绕容器的中心点旋转图像

来自分类Dev

如何使用glm :: rotate围绕原点以外的点旋转对象?

来自分类Dev

围绕鼠标旋转多个对象

来自分类Dev

HTML5围绕其中心点旋转文本

来自分类Dev

围绕中心旋转NSView

来自分类Dev

围绕中心旋转图标

来自分类Dev

围绕中心旋转NSView

来自分类Dev

围绕中心旋转图标

来自分类Dev

d3.js:如何在翻译时围绕其中心旋转SVG?