197

atanC++和C++有什么区别atan2

4

11 回答 11

371

从学校数学我们知道切线有定义

tan(α) = sin(α) / cos(α)

我们根据我们提供给函数的角度来区分四个象限。的符号sin和具有以下关系(我们忽略 的确切倍数):costanπ/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)获取所有数据,从而可以解析正确的角度。

于 2012-08-17T19:07:33.573 回答
160

std::atan2允许计算所有四个象限的反正切。std::atan只允许从象限 1 和 4 计算。

于 2008-11-12T09:22:19.523 回答
36

实际值以弧度为单位,但以度数解释它们将是:

  • atan= 给出 -90 到 90 之间的角度值
  • atan2= 给出 -180 到 180 之间的角度值

对于我的工作,涉及计算各种角度,如导航中的航向和方位,atan2在大多数情况下都可以完成这项工作。

于 2014-05-14T23:32:07.793 回答
31

另一件要提的是,当使用和为 0 或接近 0atan2之类的表达式计算切线时,它更稳定。atan(y / x)x

于 2008-11-12T17:03:16.973 回答
15

atan(x) 返回 x 的反正切的主值,以弧度表示。

atan2(y,x) 返回 y/x 的反正切的主值,以弧度表示。

请注意,由于符号不明确,函数无法确定角度仅通过其正切值(仅 atan)确定角度落在哪个象限。如果需要确定象限,可以使用 atan2。

于 2008-11-12T09:22:49.243 回答
9

我想主要问题试图弄清楚:“我什么时候应该使用其中一个”,或者“我应该使用哪个”,或者“我使用的是正确的那个”?

我想重要的一点是 atan 仅用于在向右向上的方向曲线中提供正值,例如时间距离向量。零总是在左下角,thigs 只能上下左右,只是更慢或更快。atan 不会返回负数,因此您无法仅通过添加/减去结果来跟踪屏幕上 4 个方向的内容。

atan2 旨在使原点位于中间,并且事情可以向后或向下。这就是您在屏幕表示中使用的内容,因为您希望曲线走向哪个方向确实很重要。所以 atan2 可以给你负数,因为它的零在中心,它的结果是你可以用来追踪 4 个方向的东西。

于 2014-02-09T00:48:09.567 回答
5

考虑一个直角三角形。我们标记斜边 r、水平边 y 和垂直边 x。感兴趣的角度 α 是 x 和 r 之间的角度。

C++atan2(y, x)将给我们以弧度表示的角度 α 的值。 atan如果我们只知道或只对 y/x 而不是 y 和 x 感兴趣,则使用它。因此,如果 p = y/x 则要获得 α,我们将使用atan(p).

你不能用它atan2来确定象限,你atan2只能在你已经知道你在哪个象限的情况下使用!特别是正 x 和 y 意味着第一象限,正 y 和负 x,第二象限,依此类推。atan或者atan2他们自己只是返回一个正数或负数,仅此而已。

于 2012-03-09T20:49:20.043 回答
2

使用 atan2,您可以确定此处所述的象限。

如果需要确定象限,可以使用 atan2。

于 2008-11-12T09:22:30.617 回答
1

下面的 Mehrwolf 是正确的,但这里有一个启发式可能会有所帮助:

如果您在二维坐标系中工作,这通常是编程反正切的情况,您应该使用 atan2。它将提供完整的 2 pi 角度范围,并为您处理 x 坐标中的零点。

另一种说法是 atan(y/x) 实际上总是错误的。仅当参数不能被认为是 y/x 时​​才使用 atan。

于 2016-07-11T01:46:24.017 回答
0

atan2(y,x)如果要将笛卡尔坐标转换为极坐标,通常使用。它会给你角度,sqrt(x*x+y*y)或者,如果有的话,hypot(y,x)会给你尺寸。

atan(x)只是 tan 的倒数。在恼人的情况下,您必须使用atan(y/x),因为您的系统不提供atan2,您必须对xy和的符号进行额外检查x=0,以获得正确的角度。

注意: 为和atan2(y,x)的所有实数值定义,但两个参数都为零的情况除外。yx

于 2017-03-05T15:14:21.130 回答
0

在 atan2 中,输出为:-pi< atan2(y,x)<pi
而在 atan 中,输出为:-pi/2< atan(y/x)< pi/2 //它不考虑季度。
如果你想获得和之间的方向02*pi如高中数学),我们需要使用 atan2 并且对于负值添加以获得和2*pi之间的最终结果。 这是Java源代码,可以清楚地解释它:02*pi

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
于 2018-06-21T21:04:03.880 回答