Swift实现2D点-90度旋转问题求助
解决2D点-90度旋转的问题
首先,我们得先明确一个关键信息:从你给出的输入输出结果反推,你的旋转中心不是原点,而是CGPoint(x:1, y:1)。这是之前你的函数没得到正确结果的核心原因——所有尝试都默认绕原点旋转,或者变换顺序/参数有误。
为什么旋转中心是(1,1)?
我们可以从顺时针90度(即-90度)旋转的数学公式反推:
对于绕点(originX, originY)顺时针旋转90度,旋转后的坐标(x', y')满足:
x' = originX + (y - originY) y' = originY - (x - originX)
把你的初始点(2,1)代入目标结果(1,0):
- 1 = originX + (1 - originY)
- 0 = originY - (2 - originX)
解这两个方程就能得到originX=1,originY=1。
修正你的实现方案
下面是几个可行的正确实现:
方案1:手动计算(最直观)
直接用上面推导的顺时针90度旋转公式:
func rotatePointClockwise90(_ point: CGPoint, around origin: CGPoint) -> CGPoint { let newX = origin.x + (point.y - origin.y) let newY = origin.y - (point.x - origin.x) return CGPoint(x: newX, y: newY) }
测试调用:
let topLeft = CGPoint(x: 2, y: 1) let topRight = CGPoint(x: 3, y: 1) let rotationOrigin = CGPoint(x:1, y:1) print(rotatePointClockwise90(topLeft, around: rotationOrigin)) // 输出 (1.0, 0.0) print(rotatePointClockwise90(topRight, around: rotationOrigin)) // 输出 (2.0, 0.0)
方案2:修正你的rotatePoint2函数
你的rotatePoint2逻辑是对的,但调用时必须传入正确的旋转中心,同时注意角度转弧度的正负:
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) // 弧度 let newAzimuth = azimuth + degrees * CGFloat.pi / 180.0 // 角度转弧度 let x = origin.x + radius * cos(newAzimuth) let y = origin.y + radius * sin(newAzimuth) return CGPoint(x: x, y: y) }
测试调用:
print(rotatePoint2(topLeft, -90, rotationOrigin)) // (1.0, 0.0) print(rotatePoint2(topRight, -90, rotationOrigin)) // (2.0, 0.0)
方案3:用CGAffineTransform正确实现
变换顺序很重要:先平移到旋转中心(原点)→ 旋转 → 平移回去,你的rotatePoint3变换顺序错误,修正后:
func rotatePointWithTransform(_ point: CGPoint, degrees: CGFloat, around origin: CGPoint) -> CGPoint { // 1. 平移:将点移到以旋转中心为原点的坐标系 let translateToOrigin = CGAffineTransform(translationX: -origin.x, y: -origin.y) // 2. 旋转:注意角度是弧度,顺时针旋转用负值 let rotation = CGAffineTransform(rotationAngle: degrees * CGFloat.pi / 180.0) // 3. 平移回原坐标系 let translateBack = CGAffineTransform(translationX: origin.x, y: origin.y) // 组合变换:平移到原点 → 旋转 → 平移回去 let combinedTransform = translateToOrigin.concatenating(rotation).concatenating(translateBack) return point.applying(combinedTransform) }
测试调用:
print(rotatePointWithTransform(topLeft, degrees: -90, around: rotationOrigin)) // (1.0, 0.0) print(rotatePointWithTransform(topRight, degrees: -90, around: rotationOrigin)) // (2.0, 0.0)
你之前函数的问题分析
rotatePoint1:默认绕原点旋转,没有考虑自定义旋转中心,所以结果完全不符合预期。rotatePoint2:函数逻辑正确,但你调用时没有传入旋转中心参数,导致默认绕原点旋转,自然得不到正确结果。rotatePoint3:变换顺序错误,正确的顺序应该是先平移到旋转中心,再旋转,最后平移回去,你的组合顺序搞反了。
内容的提问来源于stack exchange,提问作者Kolkos
相关产品推荐
相关产品推荐

