You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)

你之前函数的问题分析

  1. rotatePoint1:默认绕原点旋转,没有考虑自定义旋转中心,所以结果完全不符合预期。
  2. rotatePoint2:函数逻辑正确,但你调用时没有传入旋转中心参数,导致默认绕原点旋转,自然得不到正确结果。
  3. rotatePoint3:变换顺序错误,正确的顺序应该是先平移到旋转中心,再旋转,最后平移回去,你的组合顺序搞反了。

内容的提问来源于stack exchange,提问作者Kolkos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:15:33