绕点旋转点公式选型:两款JavaScript实现哪一个正确?
绕点旋转点的函数正确性验证
我对绕点旋转点的公式存在理解困惑,以下是两款来自StackOverflow热门回答的JavaScript实现:
函数1
function rotate_point_1(pointX, pointY, originX, originY, angle) { angle = angle * Math.PI / 180.0; return { x: Math.cos(angle) * (pointX-originX) - Math.sin(angle) * (pointY-originY) + originX, y: Math.sin(angle) * (pointX-originX) + Math.cos(angle) * (pointY-originY) + originY }; }
函数2
function rotate_point_2(pointX, pointY, originX, originY, angle) { angle = angle * Math.PI / 180.0; return { x: Math.cos(angle) * (pointX-originX) + Math.sin(angle) * (pointY-originY) + originX, y: Math.cos(angle) * (pointY-originY) - Math.sin(angle) * (pointX-originX) + originY } }
使用复杂数据测试时:
const r1 = rotate_point_1(-2682.124970310381, 1284.7120051002187, 2947.162670759748, 1163.2594358745218, -90); const r2= rotate_point_2(-2682.124970310381, 1284.7120051002187, 2947.162670759748, 1163.2594358745218, -90)
结果差异明显:
r1 = {x: 3068.615239985446, y: 6792.54707694465} r2 = {x: 3068.615239985446, y: 1041.8068666488261}
正确性分析
判断函数是否正确,要回到2D绕点旋转的标准公式:
绕原点旋转的核心公式(默认逆时针为正方向):
- 旋转后x坐标:
x' = x*cosθ - y*sinθ - 旋转后y坐标:
y' = x*sinθ + y*cosθ
绕任意点(originX, originY)旋转时,需要先将目标点平移到原点(减去原点坐标),旋转完成后再平移回原位置(加上原点坐标),完整公式为:
x' = cosθ*(pointX-originX) - sinθ*(pointY-originY) + originXy' = sinθ*(pointX-originX) + cosθ*(pointY-originY) + originY
这个公式和rotate_point_1的实现完全一致。
结合测试用例的-90度验证:
cos(-90°)=0,sin(-90°)=-1
代入rotate_point_1的公式计算:
x = 0*(pointX-originX) - (-1)(pointY-originY) + originX = (1284.7120051002187 - 1163.2594358745218) + 2947.162670759748 ≈ 3068.615,与结果一致
y = (-1)(pointX-originX) + 0*(pointY-originY) + originY = -(-2682.124970310381 - 2947.162670759748) + 1163.2594358745218 ≈ 6792.547,与r1的y值一致
而rotate_point_2的公式对应顺时针旋转的逻辑(或角度方向与标准定义相反),当输入负角度时,结果会和标准逆时针旋转的预期不符。
综上,rotate_point_1是符合标准逆时针旋转定义的正确实现;如果需要顺时针旋转,可直接使用rotate_point_2,或给rotate_point_1传入正角度的相反数。
内容的提问来源于stack exchange,提问作者Victor
相关产品推荐
相关产品推荐

