cpp中atan与atan2的对比
核心差异: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°。

浙公网安备 33010602011771号