web-dev-qa-db-fra.com

Quelle est la différence entre atan et atan2 en C++?

Quelle est la différence entre atan et atan2 en C++?

117
yesraaj

std::atan2 permet de calculer l'arctangente des quatre quadrants. std::atan permet uniquement de calculer à partir des quadrants 1 et 4.

100
Chris Jester-Young

En mathématiques scolaires, nous savons que la tangente a la définition

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

et nous distinguons quatre quadrants en fonction de l'angle que nous fournissons aux fonctions. Les signes de sin, cos et tan ont la relation suivante (nous négligeons les multiples exacts de π/2):

  Quadrant    Angle              sin   cos   tan
-------------------------------------------------
  I           0    < α < π/2      +     +     +
  II          π/2  < α < π        +     -     -
  III         π    < α < 3π/2     -     -     +
  IV          3π/2 < α < 2π       -     +     -

Étant donné que la valeur de tan(α) est positive, nous ne pouvons pas distinguer, si l'angle est du premier ou du troisième quadrant et s'il est négatif, il peut provenir du deuxième ou du quatrième quadrant. Donc, par convention, atan() renvoie un angle à partir du premier ou du quatrième quadrant (c'est-à-dire -π/2 <= atan() <= π/2), quelle que soit l'entrée d'origine dans la tangente.

Afin de récupérer les informations complètes, nous ne devons pas utiliser le résultat de la division sin(α) / cos(α) mais nous devons examiner les valeurs du sinus et du cosinus séparément. Et voici ce que atan2() fait. Il prend à la fois sin(α) et cos(α) et résout les quatre quadrants en ajoutant π au résultat de atan() lorsque le cosinus est négatif.

Remarque: La fonction atan2(y, x) prend en fait un argument y et x, qui est la projection d'un vecteur de longueur v et d'angle α sur les axes y et x, c'est-à-dire 

y = v * sin(α)
x = v * cos(α)

qui donne la relation

y/x = tan(α)

Conclusion: atan(y/x) retient certaines informations et ne peut que supposer que l'entrée provenait des quadrants I ou IV. En revanche, atan2(y,x) récupère toutes les données et peut donc résoudre le bon angle.

261
Mehrwolf

Une autre chose à mentionner est que atan2 est plus stable lors du calcul de tangentes utilisant une expression telle que atan(y / x) et x est égal à 0 ou proche de 0.

22
Laserallan

Les valeurs réelles sont en radians, mais pour les interpréter en degrés, ce sera:

  • atan = donne une valeur d'angle comprise entre -90 et 90
  • atan2 = donne une valeur d'angle comprise entre -180 et 180

Pour mon travail qui implique le calcul de divers angles tels que le cap et l'orientation dans la navigation, atan2 fait dans la plupart des cas le travail.

18
Keugyeol

atan (x) Renvoie la valeur principale de l'arc tangente de x, exprimée en radians.

atan2 (y, x) Renvoie la valeur principale de l'arc tangente de y/x, exprimée en radians.

Notez qu'en raison de l'ambiguïté du signe, une fonction ne peut pas déterminer avec certitude dans quel quadrant l'angle tombe uniquement par sa valeur tangente (atan seul). Vous pouvez utiliser atan2 si vous devez déterminer le quadrant.

8
Roman M

Je suppose que la question principale tente de comprendre: "quand devrais-je utiliser l'un ou l'autre", ou "lequel devrais-je utiliser" ou "Est-ce que j'utilise le bon"?

Je suppose que le point important est qu’un seul objectif était d’alimenter des valeurs positives dans une courbe directionnelle ascendante, comme pour les vecteurs temps-distance. Cero est toujours en bas à gauche, et les brindilles ne peuvent que monter et aller à droite, juste plus lentement ou plus rapidement. atan ne renvoie pas de nombres négatifs, vous ne pouvez donc pas tracer des objets dans les 4 directions sur un écran simplement en ajoutant/soustrayant son résultat.

atan2 est conçu pour que l’Origine se trouve au milieu, et les choses peuvent aller en arrière ou en bas. C’est ce que vous utiliseriez dans une représentation à l’écran, car le choix de la courbe importe peu. Donc, atan2 peut vous donner des nombres négatifs, car son cero est au centre et son résultat est quelque chose que vous pouvez utiliser pour tracer des choses dans 4 directions.

3
sergio

Avec atan2 vous pouvez déterminer le quadrant comme indiqué ici .

Vous pouvez utiliser atan2 si vous en avez besoin déterminer le quadrant.

2
Burkhard

Considérons un triangle rectangle. Nous appelons l'hypoténuse r, le côté horizontal y et le côté vertical x. L'angle d'intérêt @ est l'angle entre x et r.

c ++ atan2 (y, x) nous donnera la valeur de l'angle @ en radians . atan est utilisé si nous ne connaissons ou ne sommes intéressés par y/x pas y et x individuellement. Donc si p = y/x Alors pour obtenir @ nous utiliserions atan (p).

Vous ne pouvez pas utiliser atan2 pour déterminer le quadrant, vous pouvez utiliser atan2 uniquement si vous savez déjà quel quadrant vous êtes! En particulier, positif x et y impliquent le premier quadrant, positif y et négatif x, le second et ainsi de suite. atan ou atan2 renvoient simplement un nombre positif ou négatif, rien de plus. 

2
bheks

atan2(y,x) est généralement utilisé si vous souhaitez convertir des coordonnées cartésiennes en coordonnées polaires. Cela vous donnera l'angle, alors que sqrt(x*x+y*y) ou, si disponible, hypot(y,x) vous donnera la taille.

atan(x) est simplement l'inverse de tan. Dans le cas gênant, vous devez utiliser atan(y/x) car votre système ne fournit pas atan2; vous devez effectuer des vérifications supplémentaires pour les signes x et y et pour x=0 afin d'obtenir le bon angle.

Remarque: atan2(y,x) est défini pour toutes les valeurs réelles de y et x, à l'exception du cas où les deux arguments sont nuls.

0
user3303328

Dans atan2, le résultat est le suivant: -pi <atan2(y,x) <pi
et dans atan, le résultat est le suivant: -pi/2 <atan(y/x) <pi/2 // il ne prend PAS en compte le trimestre.
Si vous voulez obtenir l’orientation entre 0 et 2*pi (comme pour les mathématiques au lycée), vous devez utiliser atan2 et pour les valeurs négatives, ajoutez le 2*pi pour obtenir le résultat final entre 0 et 2*pi.
Voici le code source Java pour l'expliquer clairement:

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
0
user497884

Mehrwolf ci-dessous est correct, mais voici une heuristique qui peut aider:

Si vous travaillez dans un système de coordonnées à 2 dimensions, ce qui est souvent le cas pour programmer la tangente inverse, vous devez absolument utiliser atan2. Il donnera la gamme complète d'angles de 2 pi et s'occupera des zéros dans la coordonnée x pour vous.

Une autre façon de le dire est qu'atan (y/x) a pratiquement toujours tort. Utilisez seulement atan si l'argument ne peut pas être considéré comme y/x.

0
Nick Mulgan