Domanda

Qual è la differenza tra atan E atan2 nel C++?

È stato utile?

Soluzione

std::atan2 consente di calcolare l'arctangent di tutti e quattro i quadranti. std::atan consente il calcolo solo dai quadranti 1 e 4.

Altri suggerimenti

Dalla matematica della scuola sappiamo che la tangente ha la definizione

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

e differenziamo tra quattro quadranti in base all'angolo che forniamo alle funzioni. Il segno di sin, cos e tan ha la seguente relazione (dove trascuriamo i multipli esatti di π/2):

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

Dato che il valore di tan(α) è positivo, non possiamo distinguere se l'angolo fosse dal primo o terzo quadrante e se fosse negativo, potrebbe provenire dal secondo o quarto quadrante. Quindi, per convenzione, atan() restituisce un angolo dal primo o quarto quadrante (cioè -π/2 <= atan() <= π/2), indipendentemente dall'input originale alla tangente.

Per recuperare le informazioni complete, non dobbiamo usare il risultato della divisione sin(α) / cos(α) ma dobbiamo esaminare i valori di seno e coseno separatamente. E questo è ciò che atan2() fa. Prende entrambi, sin(α) e cos(α) e risolve tutti e quattro i quadranti aggiungendo π al risultato di atan2(y, x) ogni volta che il coseno è negativo.

Nota: la funzione y accetta effettivamente un x e un v argomento, che è la proiezione di un vettore con lunghezza α e angolo atan(y/x) su y - e asse x, ovvero

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

che fornisce la relazione

y/x = tan(α)

Conclusione: atan2(y,x) contiene alcune informazioni e può solo supporre che l'input provenga dai quadranti I o IV. Al contrario, <=> ottiene tutti i dati e può quindi risolvere l'angolazione corretta.

Un'altra cosa da menzionare è che atan2 è più stabile quando si calcolano tangenti usando un'espressione come atan(y / x) e x è 0 o vicino a 0.

I valori attuali sono in radianti ma per interpretarli in gradi sarà:

  • atan = fornisce un valore dell'angolo compreso tra -90 e 90
  • atan2 = fornisce un valore dell'angolo compreso tra -180 e 180

Per il mio lavoro che prevede il calcolo di varie angolazioni come la direzione e il rilevamento nella navigazione, <=> nella maggior parte dei casi fa il lavoro.

atan (x) Restituisce il valore principale dell'arco tangente di x, espresso in radianti.

atan2 (y, x) Restituisce il valore principale dell'arco tangente di y / x, espresso in radianti.

Notare che a causa dell'ambiguità del segno, una funzione non può determinare con certezza in quale quadrante l'angolo cade solo dal suo valore tangente (solo atan). Puoi usare atan2 se devi determinare il quadrante.

Immagino che la domanda principale cerchi di capire:"quando dovrei usare l'uno o l'altro", oppure "quale dovrei usare", o "Sto usando quello giusto"?

Immagino che il punto importante sia che solo atan era destinato a fornire valori positivi in ​​una curva di direzione verso destra verso l'alto come per i vettori tempo-distanza.Il cero è sempre in basso a sinistra e le cose possono solo andare in alto e a destra, solo più lentamente o più velocemente.atan non restituisce numeri negativi, quindi non puoi tracciare cose nelle 4 direzioni su uno schermo semplicemente aggiungendo/sottraendo il suo risultato.

atan2 è previsto che l'origine sia nel mezzo e le cose possono andare indietro o in basso.Questo è ciò che utilizzeresti in una rappresentazione sullo schermo, perché è importante la direzione in cui vuoi che vada la curva.Quindi atan2 può darti numeri negativi, perché il suo cero è al centro, e il suo risultato è qualcosa che puoi usare per tracciare cose in 4 direzioni.

Con atan2 è possibile determinare il quadrante come indicato qui .

  

Puoi usare atan2 se necessario   determina il quadrante.

Considera un triangolo rettangolo. Etichettiamo l'ipotenusa r, il lato orizzontale y e il lato verticale x. L'angolo di interesse @ è l'angolo tra x e r.

c ++ atan2 (y, x) ci darà il valore di angle @ in radianti. atan è usato se conosciamo o siamo interessati solo a y / x e non a y e x singolarmente. Quindi se p = y / x quindi per ottenere @ useremo atan (p).

Non puoi usare atan2 per determinare il quadrante, puoi usare atan2 solo se sai già in quale quadrante sei dentro! In particolare, xey positivo implicano il primo quadrante, y positivo e x negativo, il secondo e così via. atan o atan2 stessi restituiscono semplicemente un numero positivo o negativo, niente di più.

Mehrwolf di seguito è corretto, ma qui c'è un'euristica che può aiutare:

Se stai lavorando in un sistema di coordinate bidimensionale, che è spesso il caso della programmazione della tangente inversa, dovresti usare sicuramente atan2. Fornirà la gamma completa di 2 pi di angoli e prenderà cura degli zeri nella coordinata x per te.

Un altro modo di dire questo è che atan (y / x) è praticamente sempre sbagliato. Usa atan solo se l'argomento non può essere considerato come y / x.

atan2(y,x) viene generalmente utilizzato se si desidera convertire le coordinate cartesiane in coordinate polari. Ti darà l'angolo, mentre sqrt(x*x+y*y) o, se disponibile, hypot(y,x) ti darà la dimensione.

atan(x) è semplicemente l'inverso dell'abbronzatura. Nel fastidioso caso devi usare atan(y/x) perché il tuo sistema non fornisce atan2, dovresti fare ulteriori controlli per i segni di x e y e per x=0, al fine di ottenere l'angolazione corretta.

Nota: <=> è definito per tutti i valori reali di <=> e <=>, ad eccezione del caso in cui entrambi gli argomenti sono zero.

In atan2, l'output è: -pi < atan2(y,x) < pi
e in atan, l'output è: -pi/2 < atan(y/x) < pi/2 // NON considera il trimestre.
Se vuoi ottenere l'orientamento tra 0 e 2*pi (come la matematica del liceo), dobbiamo usare atan2 e per valori negativi aggiungi <=> per ottenere il risultato finale tra <=> e < =>.
Ecco il codice sorgente Java per spiegarlo chiaramente:

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top