Was ist der Unterschied zwischen atan und atan2 in C ++?

156

Was ist der Unterschied zwischen atanund atan2in C ++?

yesraaj
quelle

Antworten:

130

std::atan2ermöglicht die Berechnung des Arkustangens aller vier Quadranten. std::atanerlaubt nur die Berechnung aus den Quadranten 1 und 4.

Chris Jester-Young
quelle
321

Aus der Schulmathematik wissen wir, dass die Tangente die Definition hat

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

und wir unterscheiden zwischen vier Quadranten basierend auf dem Winkel, den wir den Funktionen liefern. Das Zeichen der sin, cosund tanhaben die folgende Beziehung (wo wir die genauen Vielfachen von vernachlässigen π/2):

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

Da der Wert von tan(α)positiv ist, können wir nicht unterscheiden, ob der Winkel vom ersten oder dritten Quadranten stammt, und wenn er negativ ist, könnte er vom zweiten oder vierten Quadranten stammen. Gibt also konventionell atan()einen Winkel vom ersten oder vierten Quadranten (dh -π/2 <= atan() <= π/2) zurück, unabhängig von der ursprünglichen Eingabe in die Tangente.

Um die vollständigen Informationen zurückzugewinnen, dürfen wir das Ergebnis der Division nicht verwenden, sin(α) / cos(α)sondern müssen die Werte von Sinus und Cosinus getrennt betrachten. Und genau das atan2()macht es. Es werden sowohl das als auch sin(α)und cos(α)und alle vier Quadranten aufgelöst, indem πzum Ergebnis addiert wird , atan()wann immer der Kosinus negativ ist.

Bemerkung: Die atan2(y, x)Funktion benötigt tatsächlich ein yund ein xArgument , dh die Projektion eines Vektors mit Länge vund Winkel αauf die y- und x-Achse, d. H.

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

das gibt die Beziehung

y/x = tan(α)

Schlussfolgerung: Es atan(y/x) werden einige Informationen zurückgehalten und es kann nur davon ausgegangen werden, dass die Eingabe aus den Quadranten I oder IV stammt. Im Gegensatz dazu werden atan2(y,x)alle Daten abgerufen und somit der richtige Winkel aufgelöst.

Mehrwolf
quelle
3
Ein kleines Detail, der Bereich enthält -π/2 <= atan() <= π/2tatsächlich einen Punkt ( pi/2) aus Quadrant II.
Z Boson
28

Eine andere Sache zu erwähnen ist, dass atan2sie stabiler ist, wenn Tangenten mit einem Ausdruck wie atan(y / x)und x0 oder nahe 0 berechnet werden .

Laserallan
quelle
Interessant, haben Sie eine Quelle dafür? Trifft dies allgemein oder nur für C ++ zu?
Gerard
26

Die tatsächlichen Werte sind im Bogenmaß angegeben, aber um sie in Grad zu interpretieren, ist dies:

  • atan = gibt einen Winkelwert zwischen -90 und 90 an
  • atan2 = gibt einen Winkelwert zwischen -180 und 180 an

Für meine Arbeit, bei der verschiedene Winkel wie Kurs und Peilung in der Navigation berechnet werden, ist dies atan2in den meisten Fällen der Fall.

Keugyeol
quelle
12

atan (x) Gibt den Hauptwert der Bogen-Tangente von x zurück, ausgedrückt im Bogenmaß.

atan2 (y, x) Gibt den Hauptwert der Bogen-Tangente von y / x zurück, ausgedrückt im Bogenmaß.

Beachten Sie, dass eine Funktion aufgrund der Vorzeichenmehrdeutigkeit nicht mit Sicherheit bestimmen kann, in welchen Quadranten der Winkel nur durch seinen Tangentenwert fällt (atan allein). Sie können atan2 verwenden, wenn Sie den Quadranten bestimmen müssen.

RomanM
quelle
3
atan2 (x, y) -> atan2 (y, x)
yesraaj
Der Bereich der Hauptwerte ist (-pi,pi]aber atan2 hat den Bereich, [-pi,pi]so dass er einen zusätzlichen Wert -piaus einem anderen Zweig aufgrund von atan2(-0.0,x)für enthält x<0.
Z Boson
4

Ich denke, die Hauptfrage versucht herauszufinden: "Wann sollte ich das eine oder das andere verwenden" oder "Welches soll ich verwenden" oder "Benutze ich das richtige"?

Ich denke, der wichtige Punkt ist, dass nur positive Werte in einer Richtungskurve von rechts nach oben wie bei Zeit-Distanz-Vektoren eingespeist werden sollten. Cero ist immer unten links und Thigs können nur nach oben und rechts gehen, nur langsamer oder schneller. atan gibt keine negativen Zahlen zurück, daher können Sie Dinge nicht in die 4 Richtungen auf einem Bildschirm verfolgen, indem Sie einfach das Ergebnis addieren / subtrahieren.

atan2 soll den Ursprung in der Mitte haben und die Dinge können rückwärts oder runter gehen. Das würden Sie in einer Bildschirmdarstellung verwenden, da es darauf ankommt, in welche Richtung die Kurve gehen soll. Atan2 kann Ihnen also negative Zahlen geben, da sich sein Cero in der Mitte befindet und das Ergebnis etwas ist, mit dem Sie Dinge in vier Richtungen verfolgen können.

Sergio
quelle
2

Mit atan2 können Sie den Quadranten wie hier angegeben bestimmen .

Sie können atan2 verwenden, wenn Sie den Quadranten bestimmen müssen.

Burkhard
quelle
2

Betrachten Sie ein rechtwinkliges Dreieck. Wir bezeichnen die Hypotenuse r, die horizontale Seite y und die vertikale Seite x. Der interessierende Winkel α ist der Winkel zwischen x und r.

C ++ atan2(y, x)gibt uns den Wert des Winkels α im Bogenmaß an. atanwird verwendet, wenn wir y / x nur kennen oder daran interessiert sind, nicht y und x einzeln. Wenn also p = y / x ist, würden wir verwenden, um α zu erhalten atan(p).

Sie können atan2den Quadranten nicht bestimmen, Sie können ihn atan2nur verwenden, wenn Sie bereits wissen, in welchem ​​Quadranten Sie sich befinden! Insbesondere positive x und y implizieren den ersten Quadranten, positive y und negative x, den zweiten und so weiter. atanoder atan2selbst geben einfach eine positive oder eine negative Zahl zurück, nichts weiter.

bheks
quelle
4
Wenn Sie nur noch haben p=y/x, können Sie verwenden atan2(p,1).
Mark Ransom
0

Mehrwolf unten ist richtig, aber hier ist eine Heuristik, die helfen kann:

Wenn Sie in einem zweidimensionalen Koordinatensystem arbeiten, was häufig beim Programmieren der inversen Tangente der Fall ist, sollten Sie auf jeden Fall atan2 verwenden. Es gibt den vollen Winkelbereich von 2 pi an und kümmert sich für Sie um Nullen in der x-Koordinate.

Eine andere Art, dies zu sagen, ist, dass atan (y / x) praktisch immer falsch ist. Verwenden Sie atan nur, wenn das Argument nicht als y / x angesehen werden kann.

Nick Mulgan
quelle
0

atan2(y,x)wird im Allgemeinen verwendet, wenn Sie kartesische Koordinaten in Polarkoordinaten konvertieren möchten. Es wird Ihnen den Winkel geben, währendsqrt(x*x+y*y) oder, falls verfügbar, hypot(y,x)die Größe angegeben werden.

atan(x)ist einfach die Umkehrung von tan. In dem ärgerlichen Fall, den Sie verwenden müssen, atan(y/x)weil Ihr System nicht bereitstellt atan2, müssten Sie zusätzliche Überprüfungen auf die Zeichen von xund durchführeny , und x=0, um den richtigen Winkel zu bekommen.

Hinweis: atan2(y,x) ist für alle reellen Werte von yund definiert x, außer für den Fall, dass beide Argumente Null sind.

user3303328
quelle
0

In atan2 ist die Ausgabe: -pi< atan2(y,x)< pi
und in Atan, der Ausgang ist: -pi/2< atan(y/x)< pi/2 // es nicht das Quartal betrachtet Dosis.
Wenn Sie die Orientierung zwischen 0und 2*pi(wie in der High-School-Mathematik) erhalten möchten , müssen Sie atan2 verwenden und für negative Werte das hinzufügen 2*pi, um das Endergebnis zwischen 0und zu erhalten 2*pi.
Hier ist der Java-Quellcode, um es klar zu erklären:

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