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)
您实际上是在用您的示例描述两个旋转:
- 这些点围绕 3x3 网格的中心旋转 -90 度。发生这种情况时,
topLeft
点变为 bottomLeft
,并且 topRight
变为 topLeft
。
- 然后将这些点围绕正方形中心旋转 90 度(即另一个方向),使它们再次成为
topLeft
和 topRight
。
使用来自 的这个函数:
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
找到四个角的偏移量。
我想将点旋转-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)
您实际上是在用您的示例描述两个旋转:
- 这些点围绕 3x3 网格的中心旋转 -90 度。发生这种情况时,
topLeft
点变为bottomLeft
,并且topRight
变为topLeft
。 - 然后将这些点围绕正方形中心旋转 90 度(即另一个方向),使它们再次成为
topLeft
和topRight
。
使用来自
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
找到四个角的偏移量。