绕指定点旋转平面坐标点得到非预期结果:90度旋转输出偏差问题
绕基准点旋转坐标结果与预期不符问题排查
问题场景
- 需要将坐标点
(0, 1)和(-1, 0)以原点(0, 0)为旋转中心,顺时针旋转90度,预期输出结果为(1, 0)和(0, 1) - 实际代码运行输出为:
[{'x': 1.0, 'y': 6.123233995736766e-17}, {'x': -6.123233995736766e-17, 'y': -1.0}] - 第一个点结果基本符合预期,第二个点结果符合逆时针旋转的特征,怀疑自身对旋转方向的认知存在偏差
现有实现代码
import math center = {'x': 0, 'y': 0} vertices = [{'x': 0, 'y': 1}, {'x': -1, 'y': 0}] angle = 90 def rotate(center, vertices: list, angle): radians = math.radians(angle) cos_angle = math.cos(radians) sin_angle = math.sin(radians) for vertice in vertices: temp_x = (cos_angle * (vertice['x'] - center['x'])) + (sin_angle * (vertice['y'] - center['y'])) + center['x'] temp_y = (cos_angle * (vertice['y'] - center['y'])) + (sin_angle * (vertice['x'] - center['x'])) + center['y'] vertice['x'], vertice['y'] = temp_x, temp_y return vertices
问题根因
首先可以明确:你对顺时针旋转的结果预期是完全正确的,不存在方向判定的认知偏差,问题全部来自代码实现的错误,具体分为三点:
1. 旋转矩阵公式书写错误
标准平面坐标旋转的规则是:以笛卡尔坐标系(x轴向右、y轴向上)为基准,逆时针旋转角度为正方向,对应的标准旋转矩阵公式为:
x' = cosθ*(x - x0) - sinθ*(y - y0) + x0 y' = sinθ*(x - x0) + cosθ*(y - y0) + y0
你当前写的公式存在两个核心偏差:
- x方向的计算项里,
sin和(y - y0)的组合符号错误,缺少了负号 - y方向的计算项里,把
(y - y0)和(x - x0)的系数逻辑搞混了
代入90度的三角函数值(cos90°≈0,sin90°≈1)就能看到,你写的公式实际计算效果和标准旋转逻辑完全不同。
2. 旋转方向的参数适配错误
如果需要实现顺时针旋转90度,对应数学上的旋转角度是 -90° (因为标准定义逆时针为正),这时候三角函数值为:cos(-90°)≈0,sin(-90°)≈-1。
3. 浮点数精度误差说明
你看到的输出里类似 6.12e-17 的数值,是浮点数计算的正常精度误差,实际等价于0,不需要额外处理;如果需要输出更整洁的结果,可以通过小阈值判断将接近0的值置为0即可。
修正后的实现代码
如果要实现顺时针旋转指定角度,只需要在计算弧度的时候把角度取反,同时修正旋转矩阵公式即可:
import math center = {'x': 0, 'y': 0} vertices = [{'x': 0, 'y': 1}, {'x': -1, 'y': 0}] angle = 90 # 表示顺时针旋转90度 def rotate(center, vertices: list, angle): # 顺时针旋转取负角度,匹配标准旋转矩阵的正方向定义 radians = math.radians(-angle) cos_angle = math.cos(radians) sin_angle = math.sin(radians) for vertice in vertices: dx = vertice['x'] - center['x'] dy = vertice['y'] - center['y'] # 代入标准旋转矩阵公式 temp_x = cos_angle * dx - sin_angle * dy + center['x'] temp_y = sin_angle * dx + cos_angle * dy + center['y'] vertice['x'], vertice['y'] = temp_x, temp_y return vertices
运行修正后的代码,两个点的输出就是预期的 (1, 0) 和 (0, 1),和手动推导的结果完全一致。
内容的提问来源于stack exchange,提问作者nanoman657
相关产品推荐
相关产品推荐

