Answers:
std::atan2
允许计算所有四个象限的反正切。std::atan
仅允许从象限1和4计算。
从学校数学中我们知道切线的定义
tan(α) = sin(α) / cos(α)
然后根据提供给函数的角度区分四个象限。的符号sin
,cos
并且tan
具有以下关系(我们忽略的精确倍数π/2
):
Quadrant Angle sin cos tan
-------------------------------------------------
I 0 < α < π/2 + + +
II π/2 < α < π + - -
III π < α < 3π/2 - - +
IV 3π/2 < α < 2π - + -
鉴于的值为tan(α)
正,我们无法区分该角度是来自第一象限还是第三象限,如果该角度为负,则可能来自第二象限或第四象限。因此,按照惯例,无论切线的原始输入如何,都atan()
从第一或第四象限(即-π/2 <= atan() <= π/2
)返回一个角度。
为了获取全部信息,我们不能使用除法的结果,sin(α) / cos(α)
而必须分别查看正弦和余弦的值。这是什么atan2()
呢。这需要两者的sin(α)
和cos(α)
,并通过添加解决所有四个象限π
到的结果,atan()
每当余弦为负。
备注:该atan2(y, x)
函数实际上需要一个y
和一个x
参数,它是与长度的矢量的投影v
和角度α
上的y轴和x轴,即
y = v * sin(α)
x = v * cos(α)
给出关系
y/x = tan(α)
结论:
atan(y/x)
保留了一些信息,只能假定输入来自象限I或IV。相反,atan2(y,x)
获取所有数据并因此可以解析正确的角度。
还要提到的另一件事是,atan2
当使用诸如atan(y / x)
和的表达式来计算切线并且x
为0或接近0 时,它更加稳定。
考虑一个直角三角形。我们标记斜边r,水平边y和垂直边x。感兴趣角α是x和r之间的角。
C ++ atan2(y, x)
将为我们提供以弧度为单位的角度α值。
atan
如果我们仅了解y / x或对y / x感兴趣,而不是分别对y和x感兴趣,则使用。因此,如果p = y / x,则使用α即可atan(p)
。
您不能使用atan2
确定象限,atan2
只有在您知道自己所在的象限时才可以使用!特别是,正x和y表示第一个象限,正y和负x表示第二象限,依此类推。atan
或atan2
自己只是返回一个正数或负数,仅此而已。
p=y/x
您仍然可以使用atan2(p,1)
。
在ATAN2,输出是:-pi
< atan2(y,x)
< pi
和ATAN,输出是:-pi/2
< atan(y/x)
< pi/2
//它计量不考虑四分之一。
如果您想获得介于0
和之间的方向2*pi
(例如高中数学),我们需要使用atan2,对于负值,请添加2*pi
以获得介于0
和之间的最终结果2*pi
。
以下是Java源代码,可以对其进行清晰说明:
System.out.println(Math.atan2(1,1)); //pi/4 in the 1st quarter
System.out.println(Math.atan2(1,-1)); //(pi/4)+(pi/2)=3*(pi/4) in the 2nd quarter
System.out.println(Math.atan2(-1,-1 ));//-3*(pi/4) and it is less than 0.
System.out.println(Math.atan2(-1,-1)+2*Math.PI); //5(pi/4) in the 3rd quarter
System.out.println(Math.atan2(-1,1 ));//-pi/4 and it is less than 0.
System.out.println(Math.atan2(-1,1)+2*Math.PI); //7*(pi/4) in the 4th quarter
System.out.println(Math.atan(1 ));//pi/4
System.out.println(Math.atan(-1 ));//-pi/4
-π/2 <= atan() <= π/2
实际上包括pi/2
象限II中的一个点()。