A cosa servono atan e atan2 nei giochi?


48

Ho qualche problema a capire Math.tan()e Math.atan()e Math.atan2().

Ho una conoscenza di base della trigonmetria, ma l'uso di SIN, COS, TAN ecc. Per lo sviluppo di giochi è molto nuovo per me.

Sto leggendo alcuni tutorial e vedo che usando la tangente possiamo ottenere l'angolo in cui un oggetto deve essere ruotato di quanto deve affrontare un altro oggetto, ad esempio il mio mouse. Quindi perché dobbiamo ancora usare atan o atan2?


atan è usato per determinare l'angolo, utile per mille cose diverse. Hai una vera domanda sul suo utilizzo o stai solo cercando un aiuto matematico generale?
BlueRaja - Danny Pflughoeft l'

5
Hai sicuramente bisogno di capire la matematica / geometria dietro quelle funzioni; una volta che li padroneggerai, diventeranno parte della tua "comprensione del mondo", come la grammatica di base che usi tutti i giorni per parlare. Quando sarai in grado di "parlare matematica / geometria", vedrai che quelle funzioni sono strumenti semplici per ottenere un risultato, il più naturale da usare.
FxIII,

Quei tutorial sono sbagliati o hai frainteso. Usa atan2 () per ottenere l'angolo da un oggetto a un altro. Di seguito è spiegato come funziona.
scherzare il

grazie alla gente per le risposte, ora mi
pento di

Risposte:


94

La formula tangente è questa:

tan(angle) = opposite/adjacent

Fare riferimento a questo disegno:

Schema di un triangolo rettangolo, con un angolo theta e i suoi lati opposti e adiacenti segnati

Dov'è ail lato adiacente, oè il lato opposto ed thetaè l'angolo. Allo stesso modo, seno e coseno sono sin (ang) = o / h e cos (ang) = a / h dov'è hil lato lungo: http://www.mathwords.com/s/sohcahtoa.htm

Nel frattempo atan(abbreviazione di tangente ad arco , noto anche come tangente inversa ) è il contrario di tan, in questo modo:

atan(opposite/adjacent) = angle

Pertanto, se si conoscono i valori di entrambi i lati opposti e adiacenti (ad esempio sottraendo le coordinate dell'oggetto dalle coordinate del mouse) è possibile ottenere il valore dell'angolo con atan.

Nello sviluppo del gioco, tuttavia, può succedere abbastanza spesso che il lato adiacente sia uguale a 0 (ad esempio, la coordinata x di un vettore è 0). Ricordando che tan(angle) = opposite/adjacentil potenziale per un disastroso errore di divisione per zero dovrebbe essere chiaro. Così un sacco di librerie offrono una funzione chiamata atan2, che consente di specificare sia le xe yparametri, per evitare la divisione per zero per voi e dare un angolo nel quadrante destro.

diagramma atan2

(diagramma per gentile concessione di Gareth, vota anche la sua risposta)


L'uso della trigonometria nello sviluppo del gioco è abbastanza comune, specialmente con i vettori, ma di solito le biblioteche nascondono il lavoro della trigonometria per te. Puoi usare sin / cos / tan per molte attività che coinvolgono manipolazioni geometriche per trovare un valore da un triangolo. Tutto ciò di cui hai bisogno sono 3 valori (lunghezze laterali / valori dell'angolo) per trovare gli altri valori di un triangolo rettangolare, quindi è abbastanza utile.

Puoi anche usare la natura "ciclica" delle funzioni seno e coseno per comportamenti speciali in un gioco, ad esempio ho visto cos / sin usato molto per far girare un oggetto attorno ad un altro.


8
Vale la pena notare che Wikipedia descrive altri usi di Atan2 ( non atan) oltre a evitare la divisione per zero. Ad esempio, si corregge da solo per il quadrante in uso, dove normalmente dovresti fare tutto da solo.
doppelgreener,

Anzi, nota molto importante proprio lì. Aggiornamento della mia risposta.
Jesse Emond,

Non ti sei abbronzato e atan al contrario nel tuo primo lungo paragrafo? Dovresti usare atan per ottenere l'angolo (cioè invertire l'equazione) e tan per ottenere il rapporto dei lati (cioè esattamente ciò che dice l'equazione).
scherzando il

Bene, se sai che o / a è uguale ad esempio a 3, allora se vuoi l'angolo che fai atan (3), questo è quello che intendevo dire: se vuoi isolare l'angolo, usi atan sul rapporto. Se si desidera isolare il rapporto, utilizzare l'abbronzatura sull'angolo.
Jesse Emond,

Allora cambierò la tua formulazione, perché sembra che tu stia dicendo il contrario.
scherzare il

64

inserisci qui la descrizione dell'immagine


1
Sarebbe scortese modificare la risposta migliore per avere questo diagramma? Questo diagramma è fantastico e si adatterebbe subito dopo la spiegazione scritta di atan2 () di Jesse.
deridere il

1
Vai avanti: sii mio ospite! Eliminerò questa risposta dopo aver terminato.
Gareth Rees,

7
No Continuate così! È accreditato e la gente dovrebbe ancora votare qui per il diagramma.
Jesse Emond,

12

Ecco un modo leggermente diverso di pensare alle funzioni trig - incluso atan () e atan2 () - che trovo utile (le spiegazioni in termini di "opposto / adiacente" mi confondono per qualche motivo).

x, y, r, theta

Puoi spostarti da un punto all'altro spostando le unità x in orizzontale e le unità y in verticale (chiamate coordinate rettangolari o cartesiane ) o spostando la distanza r con un angolo di Ɵ (chiamate coordinate polari in 2D).

Supponiamo di avere una coordinata polare (r, Ɵ) e di convertirla in (x, y).

cos (Ɵ) ti dà la proporzione di r che si trova lungo l' asse x :

  • Se r = 1 allora x = cos (Ɵ).
  • Se r = 100, allora x = 100 * cos (Ɵ).
  • In generale x = r * cos (Ɵ).

Allo stesso modo sin (Ɵ) ti dà la proporzione di r che si trova lungo l' asse y :

  • Se r = 1 allora y = sin (Ɵ).
  • Se r = 100 allora y = 100 * sin (Ɵ).
  • In generale y = r * sin (Ɵ).

Che ne dici di convertire le coordinate rettangolari (x, y) in coordinate polari (r, Ɵ)?

r è l'ipotenusa del triangolo rettangolo formato da x ed y , quindi:

  • r = sqrt (x x + y y)

l'abbronzatura (Ɵ) indica la pendenza - l'aumento sopra la corsa - della linea con lunghezza r . Così:

  • tan (Ɵ) = y / x
  • Ɵ = atan (y / x)

Tuttavia, quando si esegue y / x, il calcolo di 3/4 dà la stessa risposta del calcolo di -3 / -4. Allo stesso modo -3/4 dà la stessa risposta di 3 / -4. Quindi abbiamo atan2 (y, x) che gestisce correttamente i singoli segni e previene un errore di divisione per zero / infinito.

  • Ɵ = atan2 (y, x)

4

Jesse e Sid hanno sostanzialmente ragione, ma sospetto che tu stia davvero cercando di capire il problema.

Atan2 () è necessario in quanto atan () non ti dice l'angolo dall'orizzontale di cui hai bisogno in quanto non affronta i quadranti.

Ciò significa che l'uso di atan per i vettori (-2,2) e (2, -2) darà lo stesso valore. Dovresti quindi attivare il segno dei tuoi argomenti e aggiungere pi al risultato. Inoltre, hai la divisione per zero caso speciale da considerare che Jesse ha menzionato. Anche atan2 () funziona meglio di atan quando x è vicino a 0

Quindi se vuoi l'angolo di un vettore tra -pi e pi

x = -2
y = 2
angle = Math.Atan2(y, x)

o

x = -2
y = 2
angle = calculateAngle(y, x);

double CalculateAngle(double y, double x)
{
    double angle = 0;
    if (x == 0)
    {
        if (y == 0)
            angle = 0;
        else if (y > 0)
            angle = Math.PI/2;
        else
            angle = -Math.PI/2;
    }
    else
    {
        angle = Math.Atan(y/x);
        if (x < 0)
        {
            if (y > 0)
            {
                angle += Math.PI;
            }
            else if (y < 0)
            {
                angle -= Math.PI;
            }
            else
            {
                angle = Math.PI;
            }
        }
    }
    return angle;
}

1
"Ciò significa che l'uso di atan per i vettori (-2,2) e (2,2) darà lo stesso valore." In questo caso il tuo atan è incredibilmente rotto, perché uno di questi dovrebbe essere -π / 4 e l'altro π / 4. Peccato per tutti coloro che hanno votato questa spazzatura.

Il codice è ancora sbagliato. Stai testando per y==0poi dividerlo xnell'altro ramo.
Sam Hocevar,

0

Chiarirò alcune cose in modo conciso. Fare riferimento ai tutorial di trigonometria online per una spiegazione dettagliata.

Lascia che sia un angolo. Quindi tan (a) = tan (a + 2 * pi).

atan è l'abbronzatura inversa, cioè ti dà l'angolazione data l'abbronzatura. Quando chiami atan (tan (a + 2 * pi)), la risposta sarà a. Questo sarà inadeguato per la tua applicazione.

atan2 prenderà 2 argomenti per aiutare queste situazioni esatte. atan prende xey, che sono fondamentalmente cos (a) e sin (a).

atan2 (sin (a), cos (a)) = a atan2 (sin (a + 2 * pi), cos (a + 2 * pi)) = a + 2 * pi / * sin e cos ha segni diversi, che portano a una risposta diversa * /

Si prega di trovare alcuni tutorial per spiegare perché questo è così.

Il tuo codice dovrebbe essere qualcosa del genere:

if (mouseMoved)
{
  double angle = atan2(mousey - objecty, mousex - objectx);

  object. setTransform to Rotate(angle);

  // If you want to print it
  print radian_to_degrees(angle); // Because angle is in radian 360 degrees = 2*Pi radians
}

tan(a) = - tan(-a), l'equazione che volevi esprimere era forsetan(a) = tan(pi+a)
Ali1S232,

0

Un uso che atan2ho trovato nel mio codice è "angolo firmato".

Normalmente è come trovare l'angolo tra due vettori

inline float angleWith( const Vector2f& o ) const
{
    return acosf( this->normalizedCopy().dot(o.normalizedCopy()) ) ;
}

Ma questo non ti dice quale "conduce" (cioè è "più avanti in senso orario" rispetto all'altro). Queste informazioni possono essere importanti per il rilevamento dei gesti.

Potresti trovare l'angolo dall'asse x (1,0)per entrambi i vettori, ma c'è questo brutto problema di ambiguità: un vettore con un angolo di 315 gradi restituisce 45 gradi usando il cosmetodo sopra, e così fa un angolo di 45 gradi. Potresti fare un segno di spunta yper risolvere il problema, oppure potresti usare atan2.

// Returns + if this leads o.
// more expensive than unsigned angle.
inline float signedAngleWith( const Vector2f& o ) const
{
  float aThis = atan2f( y, x );
  float aO = atan2f( o.y, o.x ) ;
  return aThis - aO ;
}

0

Nota che atan non è rotto. l'arcano o l'abbronzatura inversa sono solo una funzione tra -PI / 2 e PI / 2. Ripete questo schema ma non è una funzione che è un problema per un computer in quanto non gestisce risposte multiple.

Questo è lo stesso per un asin tra -PI / 2 e PI / 2 e acos tra 0 e PI. Questi sono gli intervalli più semplici per l'esecuzione di una funzione. Per atan e asin va dal più negativo al più positivo. Per acos va dal più positivo al più negativo. (questo aiuta a interpolare risposte più accurate)

così asin, acos e atan sono le funzioni matematiche.

atan2 tuttavia è molto più utile per la programmazione in quanto fornisce la rivoluzione completa (PI in radianti o 360 gradi o 400 gradienti). Nota che ne hanno prodotto solo uno per l'abbronzatura, non per il peccato o il cos. L'abbronzatura è l'unica che utilizza orizzontale e verticale (x, y)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.