核心差异:atan 是单参数、无象限区分、范围窄;atan2 是双参数、有象限区分、范围全,且无需提前做除法;
工程选择:SLAM / 机器人 / 图形学等需要精准计算角度的场景,优先用 atan2(y, x);atan 仅适用于已知角度在 [-90°, 90°] 的简单场景;
代码意义:atan2 是四元数转角度轴代码中角度计算 “准确、稳定” 的关键,避免了 atan 的除零、象限丢失、精度损失问题。
点击查看代码
// 第一步:先定义宏(必须在#include <cmath>之前)
#define _USE_MATH_DEFINES
#include<iostream>
#include<cmath>
#include<iomanip> //用于格式化输出
#include<string>
// 弧度转角度的辅助函数
double rad2deg(double rad) {return rad * 180 / M_PI;
}
int main() {//定义四个象限的测试点(覆盖不同符号组合)double points[4][2] = {{1,1},//第一象限{-1,1},//第二象限{-1,-1},//第三象限};std::string quadrants[4] = { "第一象限","第二象限", "第三象限", "第四象限" };std::cout << std::fixed << std::setprecision(2);std::cout << "======atan vs atan2 对比=========\n";std::cout << "象限\t坐标(x,y)\t斜率(y/x)\tatan(斜率)(°)\tatan2(y,x)(°)\t实际角度(°)\n";std::cout << "---------------------------------------------\n";for (int i = 0; i < 4; ++i){double x = points[i][0];double y = points[i][1];double slope = y / x;// 计算斜率(atan的输入)double atan_result = rad2deg(atan(slope));//atan结果(角度)double atan2_result = rad2deg(atan2(y, x));//atan2计算结果(角度)double actual_angle = atan2_result;//实际角度就是atan2的结果std::cout << quadrants[i] << "\t(" << x << "," << y << ")\t"<< slope << "\t\t" << atan_result << "\t\t"<< atan2_result << "\t\t" << actual_angle << "\n";}//特殊值测试:x=0(y轴方向)std::cout << "\n====特殊轴测试(x=0)=======\n";double x0 = 0, y1 = 1, y2 = -1;std::cout << "坐标(0,1):actan(1/0)->除零错误:atan(1.0)=" << rad2deg(atan2(y1, x0)) << "°n";std::cout << "坐标(0,-1):atan(-1/0) → 除零错误;atan2(-1,0) = " << rad2deg(atan2(y2, x0)) << "°\n";return 0;
}

关键结论:
第一 / 第四象限:atan 和 atan2 结果一致(因为斜率符号能反映角度);
第二 / 第三象限:atan 完全错判(比如第二象限实际 135°,atan 返回 - 45°),而 atan2 精准匹配实际角度;
特殊值(x=0):atan 直接失效(除零),atan2 能正确返回 90°/-90°。