Вращение CGPoint вокруг другого CGPoint

Итак, я хочу повернуть CGPoint(A) на 50 градусов вокруг CGPoint(B). Есть ли хороший способ сделать это?

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

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

Вот что я хочу сделать:

Иллюстрация


person Benja0906    schedule 28.02.2016    source источник


Ответы (2)


Это действительно математический вопрос. В 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, но я оставил его подробным для ясности.

person Grimxn    schedule 28.02.2016
comment
Это сработало идеально! Единственный ответ, который я нашел, работает без использования CGAffineTransform - person bevbomb; 23.11.2016

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)
person EdwardSanchez    schedule 26.11.2017
comment
Не уверен, что понимаю ваше значение по умолчанию... по умолчанию это будет довольно произвольная точка ‹0,5, 0,5› (конечно, ‹0,0› было бы лучше?), а origin будет только nil, если это явно установлено как nil, и в этом случае функция ничего не сделает...? Некоторые комментарии помогут, возможно... - person Grimxn; 03.05.2018