Swift: 在二维中旋转点

Swift: make rotation of point in 2D

我想将点旋转-90度

初始

决赛

让我们来看看Initial的左上角和右上角。他们的坐标是:

let topLeft = CGPoint(x: 2, y: 1)  
let topRight = CGPoint(x: 3, y: 1) 

旋转后它们的坐标应该变成:

topLeft 1:0
topRight 2:0

我该怎么做?

我尝试了几个答案,但 none 给出了我的最终结果。

无效:

What is the best way to rotate a CGPoint on a grid?

以下是我的 playground 中的一些代码:

 let topLeft = CGPoint(x: 2, y: 1)   
 let topRight = CGPoint(x: 3, y: 1)  

 func rotatePoint1(_ point: CGPoint, _ degrees: CGFloat) -> CGPoint {
     let s = CGFloat(sinf(Float(degrees)))
     let c = CGFloat(cosf(Float(degrees)));
     return CGPoint(x: c * point.x - s * point.y, y: s * point.x + c * point.y)
 }

 func rotatePoint2(_ point: CGPoint, _ degrees: CGFloat, _ origin: CGPoint) -> CGPoint {
     let dx = point.x - origin.x
     let dy = point.y - origin.y
     let radius = sqrt(dx * dx + dy * dy)
     let azimuth = atan2(dy, dx) // in radians
     let newAzimuth = azimuth + degrees * 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)
 }

 func rotatePoint3(_ point: CGPoint, _ degrees: CGFloat) -> CGPoint {
     let translateTransform = CGAffineTransform(translationX: point.x, y: point.y)
     let rotationTransform = CGAffineTransform(rotationAngle: degrees)
     let customRotation = (rotationTransform.concatenating(translateTransform.inverted())).concatenating(translateTransform)
     return point.applying(customRotation)
 }

 print(rotatePoint1(topLeft, -90))
 print(rotatePoint1(topRight, -90))

你可以像这样变换你的视图

yourView.transform = CGAffineTransform(rotationAngle: -CGFloat.pi/2)

编辑: 我的错。

在处理度数时使用 CGFloat.pi

print(rotatePoint1(topLeft, -CGFloat.pi/2))

直接使用sin和cos函数

let s = sin(degrees)
let c = cos(degrees)

iOS 坐标系与标准坐标系相比有点翻转,所以你必须调整角度(你可以看到 simulation

print(rotatePoint1(topLeft, -CGFloat.pi/2)) // (1.0000000000000002, -2.0)
print(rotatePoint1(topRight, -CGFloat.pi/2)) // (1.0000000000000002, -3.0)

您实际上是在用您的示例描述两个旋转:

  1. 这些点围绕 3x3 网格的中心旋转 -90 度。发生这种情况时,topLeft 点变为 bottomLeft,并且 topRight 变为 topLeft
  2. 然后将这些点围绕正方形中心旋转 90 度(即另一个方向),使它们再次成为 topLefttopRight

使用来自 的这个函数:

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 * .pi / 180 // convert it to radians
    let x = origin.x + radius * cos(newAzimuth)
    let y = origin.y + radius * sin(newAzimuth)
    return CGPoint(x: x, y: y)
}

let topLeft = CGPoint(x: 2, y: 1)
let topRight = CGPoint(x: 3, y: 1)
let squareCenter = CGPoint(x: 2.5, y: 1.5)

// First rotate around the center of the 3 x 3 square
let centerOfRotation = CGPoint(x: 1.5, y: 1.5)

let tl1 = rotatePoint(target: topLeft, aroundOrigin: centerOfRotation, byDegrees: -90)  // (x 1 y 1)
let tr1 = rotatePoint(target: topRight, aroundOrigin: centerOfRotation, byDegrees: -90) // (x 1 y 0)
let sc1 = rotatePoint(target: squareCenter, aroundOrigin: centerOfRotation, byDegrees: -90)  // (x 1.5 y 0.5)

// Now rotate the 1x1 square the other way around new position of square center
let tl2 = rotatePoint(target: tl1, aroundOrigin: sc1, byDegrees: 90)  // (x 1 y 0)
let tr2 = rotatePoint(target: tr1, aroundOrigin: sc1, byDegrees: 90)  // (x 2 y 0)

注意:正如@MBo 在评论中指出的那样,如果您的单元格始终为 1x1,则旋转单元格的中心就足够了,然后只需添加和减去 0.5 找到四个角的偏移量。