绕另一个 CGPoint 旋转一个 CGPoint

5

好的,我想围绕CGPoint(B)旋转50度来旋转CGPoint(A),有没有好的方法?

CGPoint(A) = CGPoint(x: 50, y: 100)

CGPoint(B) = CGPoint(x: 50, y: 0)

这是我想做的:

Illustration

2个回答

15

这其实是一个数学问题。在Swift中,你需要这样写:

func rotatePoint(target: CGPoint, aroundOrigin origin: CGPoint, byDegrees: CGFloat) -> CGPoint {
    let dx = target.x - origin.x
    let dy = target.y - origin.y
    let radius = sqrt(dx * dx + dy * dy)
    let azimuth = atan2(dy, dx) // in radians
    let newAzimuth = azimuth + byDegrees * CGFloat(M_PI / 180.0) // convert it to radians
    let x = origin.x + radius * cos(newAzimuth)
    let y = origin.y + radius * sin(newAzimuth)
    return CGPoint(x: x, y: y)
}

有很多方法可以简化这个问题,而且这是使用 CGPoint 扩展的完美案例,但为了清晰起见,我保持了冗长。

有很多方法可以简化这个问题,而且这是使用 CGPoint 扩展的完美案例,但为了清晰起见,我保持了冗长。

这个方法完美地运行了!这是我找到的唯一一个在不使用CGAffineTransform的情况下起作用的答案。 - bevbomb

-1
public extension CGFloat {
    ///Returns radians if given degrees
    var radians: CGFloat{return self * .pi / 180}
}    

public extension CGPoint {
    ///Rotates point by given degrees
    func rotate(origin: CGPoint? = CGPoint(x: 0.5, y: 0.5), _ byDegrees: CGFloat) -> CGPoint {
        guard let origin = origin else {return self}

        let rotationSin = sin(byDegrees.radians)
        let rotationCos = cos(byDegrees.radians)

        let x = (self.x * rotationCos - self.y * rotationSin) + origin.x
        let y = (self.x * rotationSin + self.y * rotationCos) + origin.y

        return CGPoint(x: x, y: y)
    }
}

使用方法

var myPoint = CGPoint(x: 40, y: 50).rotate(45)
var myPoint = CGPoint(x: 40, y: 50).rotate(origin: CGPoint(x: 0, y: 0), 45)

我不确定我理解你的默认设置...默认情况下,它将是相当任意的点<0.5,0.5>(肯定<0,0>会更好吧?),只有当显式地将其设置为nil时,origin才会为nil,在这种情况下函数将什么也不做...也许一些注释会有所帮助... - Grimxn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接