Math.atan2(y, x) 参数顺序为先y后x,返回[-π, π]弧度值,需手动归一化到0–360°,边界情况需单独判断,转角度应使用Math.PI而非近似值。

Math.atan2(y, x) 的参数顺序别搞反
很多人写成 Math.atan2(x, y),结果角度全错——它严格要求先传 y(纵坐标),再传 x(横坐标)。因为本质是计算 y / x 的反正切,且需靠两者的符号组合判断象限。传反了,y 和 x 的正负逻辑就崩了,比如点 (1, -1) 本该在第四象限(-45°),传成 atan2(1, -1) 就变成第二象限(135°)。
角度范围 [-π, π] 是设计,不是 bug
Math.atan2() 返回值永远落在 [-Math.PI, Math.PI] 区间,这是为了统一覆盖全部四个象限和坐标轴边界。这意味着第三象限的点(如 (-1, -1))返回的是 -2.35619(即 -135°),而不是 2.28319(225°)。如果你需要 0–360° 范围,得手动归一化:
const angleRad = Math.atan2(y, x); const angle360 = angleRad < 0 ? angleRad + 2 * Math.PI : angleRad;
不处理这一步,直接用 angleRad 做插值、旋转或 UI 角度映射时,会出现跳变(比如从 -179° 突然跳到 +179°)。
坐标轴边界和原点要单独判断
Math.atan2() 对边界情况有明确定义,但容易被忽略:
- 当
y === 0 && x > 0→ 返回0(正东) - 当
y === 0 && x < 0→ 返回Math.PI(正西) - 当
y > 0 && x === 0→ 返回Math.PI / 2(正北) - 当
y < 0 && x === 0→ 返回-Math.PI / 2(正南) - 当
y === 0 && x === 0→ 返回0(注意:这不是错误,但业务上通常应拒绝原点输入)
如果你用角度做方向分类(比如“朝北”“朝东南”),直接按数值区间切分会漏掉这些边界;建议先判断 x 和 y 是否为零,再进角度逻辑。
从弧度转角度别硬编码 180 / 3.1415926
用 angleRad * 180 / Math.PI 没问题,但更稳妥的是封装或复用已有方法:
const deg = Math.toDegrees?.(rad) || (rad * 180 / Math.PI); // 注意:Math.toDegrees 是 Java/Android API,JS 中没有
JavaScript 标准里没有 Math.toDegrees(),所以必须手算。常见错误是用 3.14 或 Math.PI.toFixed(2) 截断,导致精度丢失——尤其在做高精度方位差(如陀螺仪融合)时,0.01° 的误差可能放大成明显偏差。
真正麻烦的从来不是算出一个数,而是你默认它“能直接用”。象限分布、坐标轴对齐、0/360 接口、浮点零值处理——这些细节堆在一起,才决定 Math.atan2() 是帮你省事,还是埋雷。

















