根据我的理解,atan2()
函数存在于编程语言中,因为atan()
本身不能总是确定正确的θ,因为输出被限制为-pi / 2到pi / 2。
如果是这种情况,那么同样的问题同时适用于asin()
和acos()
,两者都有限制范围,那么为什么没有asin2()
和acos2()
函数呢?
首先,请注意语法是atan(y/x)
但是atan2(y, x)
,而不是atan2(y/x)
。这很重要,因为通过不执行划分,您提供了额外的信息,最重要的是x
和y
的个别标志。如果你分别知道x
和y
坐标,你知道角度,包括象限。
如果你从tan(θ) = y/x
到sin(θ) = y/sqrt(x²+y²)
,那么逆操作asin
需要y
和sqrt(x²+y²)
并结合它来获得有关角度的一些信息。在这里,无论我们是自己执行分裂还是让一些假设的asin2
函数处理它都没关系。分母总是正的,因此分割的参数包含与单独的分子和分母包含的信息一样多的信息。 (至少在IEEE环境中,除以零会导致正确签名的无穷大。)
如果你知道y
坐标和hypothenuse sqrt(x²+y²)
然后你知道角度的正弦,但你不能知道角度本身,因为你无法区分负和正x
值。同样,如果你知道x
坐标和hypothenuse,你知道角度的余弦,但你不知道y
值的符号。
所以asin2
和acos2
在数学上是不可行的,至少不是以明显的方式。如果你将某种符号编码到连字符中,事情可能会有所不同,但我认为这种符号不会自然出现。
有时需要像“acos2”这样的功能,例如在3D空间中执行矢量旋转时。在这种情况下,我硬编码我自己的acos2函数,它只执行以下检查:
x_perp=sqrt(x*x+y*y)
r=sqrt(x*x+y*y+z*z)
if(x_perp.gt.0.0d0) then
phi=acos(x/x_perp)
else
phi=0.0d0
endif
if(y.lt.0.0d0) phi=2.0d0*pi-phi
theta=acos(z/r)
其中theta和phi是通常的球面坐标,而x,y,z是笛卡尔坐标。当y为负时,问题出现,需要在phi中发生相移。对于theta没有这样的问题。
我将以这种方式用简单的术语解释。 有关以下说明,请参阅此图像:
任务:选择一个能够跟踪-180 < θ < 180
范围内正确角度的函数
试验1:sin()
在第一和第二象限sin(30) = sin(150) = 0.5
中呈阳性。用sin()
跟踪象限变化并不容易。
因此,asin2()
是不可行的。
试验2:cos()
在第一和第四象限cos(60) = sin(300) = 0.5
呈阳性。此外,使用cos()
跟踪象限变化并不容易。
因此,acos2()
再次不可行。
试验3:tan()
在第一和第三象限中是积极的,并且是有趣的顺序。
第1象限为正,第2象为正,第3象为正,第4象为负,第4象限为正。
这样的tan(45) = 1
,tan(135) = -1
,tan(225) = 1
,tan(315) = -1
和tan(360+45) = 1
。欢呼!我们可以跟踪象限变化。
请注意,明确的范围是-180 < θ < 180
。另外,请注意上面我的45度增量示例,如果序列是1,-1,..
,则角度逆时针方向,如果序列是-1,1,..
则顺时针方向。这个想法应该解决方向性。
因此,atan2()
成为我们的选择。