ios - Swift:在 2D 中旋转点
问题描述
我想将点旋转-90度
最初的
最终的
让我们看一下 Initial 的左上角和右上角。它们的坐标是:
let topLeft = CGPoint(x: 2, y: 1)
let topRight = CGPoint(x: 3, y: 1)
并且在它们的旋转坐标之后应该变成:
topLeft 1:0
topRight 2:0
我该怎么做 ?
我尝试了几个答案,但没有一个给出我的最终结果。
不起作用: 围绕另一个 CGPoint 旋转一个 CGPoint
以下是我操场上的一些代码:
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))
解决方案
你真的用你的例子描述了两个旋转:
- 这些点围绕 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
偏移量即可找到四个角。
推荐阅读
- python - 在 S3 中压缩文件
- go - 当 xerrors.Errorf() 输出错误时,有什么方法可以设置 xerrors.Caller(1)?
- ios - 根据屏幕尺寸翻译/缩放 UIImageViews
- c - 在C中将度数转换为弧度时结果令人困惑
- angular - 点击后永久禁用按钮
- sql - 无法在 oracle SQL 开发人员中更新内部 if 条件
- azure - 在云中托管 Azure IoT-HuB 设备客户端
- bash - shell - 将命令行参数传递给 bash 脚本不起作用
- python - Python 的 Stacktrace 在 psycopg2 connection.notices 中被截断
- regex - 注释行与 Ansible 匹配一些模式和后面的 n 个字符串