Perché usiamo il teorema di Pitagora nella fisica dei giochi?


38

Di recente ho imparato che usiamo molto il teorema di Pitagora nei nostri calcoli di fisica e temo di non capire davvero il punto.

Ecco un esempio di un libro per assicurarsi che un oggetto non viaggi più velocemente di una MAXIMUM_VELOCITYcostante sul piano orizzontale:

MAXIMUM_VELOCITY = <any number>;
SQUARED_MAXIMUM_VELOCITY = MAXIMUM_VELOCITY * MAXIMUM_VELOCITY; 

function animate(){
    var squared_horizontal_velocity = (x_velocity * x_velocity) + (z_velocity * z_velocity);

    if( squared_horizontal_velocity <= SQUARED_MAXIMUM_VELOCITY ){

        scalar = squared_horizontal_velocity / SQUARED_MAXIMUM_VELOCITY;

        x_velocity = x_velocity / scalar;
        z_velocity = x_velocity / scalar;
    }
}

Proviamo questo con alcuni numeri:

Un oggetto sta tentando di spostare 5 unità in xe 5 unità in z. Dovrebbe essere in grado di muovere solo 5 unità in orizzontale in totale!

MAXIMUM_VELOCITY = 5;
SQUARED_MAXIMUM_VELOCITY = 5 * 5;
SQUARED_MAXIMUM_VELOCITY = 25;

function animate(){
    var x_velocity = 5;
    var z_velocity = 5;

    var squared_horizontal_velocity = (x_velocity * x_velocity) + (z_velocity * z_velocity);
    var squared_horizontal_velocity = 5 * 5 + 5 * 5;
    var squared_horizontal_velocity = 25 + 25;
    var squared_horizontal_velocity = 50;

//  if( squared_horizontal_velocity <= SQUARED_MAXIMUM_VELOCITY ){
    if( 50 <= 25 ){
        scalar = squared_horizontal_velocity / SQUARED_MAXIMUM_VELOCITY;
        scalar = 50 / 25;
        scalar = 2.0;

        x_velocity = x_velocity / scalar;
        x_velocity = 5 / 2.0;
        x_velocity = 2.5;

        z_velocity = z_velocity / scalar;
        z_velocity = 5 / 2.0;
        z_velocity = 2.5;

        // new_horizontal_velocity = x_velocity + z_velocity
        // new_horizontal_velocity = 2.5 + 2.5
        // new_horizontal_velocity = 5
    }
}

Ora funziona bene, ma possiamo fare la stessa cosa senza Pitagora:

MAXIMUM_VELOCITY = 5;

function animate(){
    var x_velocity = 5;
    var z_velocity = 5;

    var horizontal_velocity = x_velocity + z_velocity;
    var horizontal_velocity = 5 + 5;
    var horizontal_velocity = 10;

//  if( horizontal_velocity >= MAXIMUM_VELOCITY ){
    if( 10 >= 5 ){
        scalar = horizontal_velocity / MAXIMUM_VELOCITY;
        scalar = 10 / 5;
        scalar = 2.0;

        x_velocity = x_velocity / scalar;
        x_velocity = 5 / 2.0;
        x_velocity = 2.5;

        z_velocity = z_velocity / scalar;
        z_velocity = 5 / 2.0;
        z_velocity = 2.5;

        // new_horizontal_velocity = x_velocity + z_velocity
        // new_horizontal_velocity = 2.5 + 2.5
        // new_horizontal_velocity = 5
    }
}

Vantaggi del farlo senza Pitagora:

  1. Meno righe
  2. All'interno di queste righe, è più facile leggere cosa sta succedendo
  3. ... e richiede meno tempo per il calcolo, poiché ci sono meno moltiplicazioni

Mi sembra che i computer e gli umani ottengano un affare migliore senza il teorema di Pitagora! Tuttavia, sono sicuro di sbagliarmi poiché ho visto il teorema di Pitagora in un certo numero di luoghi affidabili, quindi vorrei che qualcuno mi spiegasse il vantaggio di usare il teorema di Pitagora per un neofita della matematica .

Questo ha qualcosa a che fare con i vettori di unità? Per me un vettore unitario è quando normalizziamo un vettore e lo trasformiamo in una frazione. Lo facciamo dividendo il vettore per una costante più grande. Non sono sicuro di cosa sia costante. La dimensione totale del grafico? Comunque, poiché è una frazione, lo prendo, un vettore di unità è fondamentalmente un grafico che può adattarsi all'interno di una griglia 3D con l'asse x che va da -1 a 1, l'asse z che corre da -1 a 1 e y -asse che va da -1 a 1. Questo è letteralmente tutto ciò che so sui vettori di unità ... non molto: P E non riesco a vedere la loro utilità.

Inoltre, non stiamo davvero creando un vettore unitario negli esempi precedenti. Dovrei determinare lo scalare in questo modo:

// a mathematical work-around of my own invention. There may be a cleverer way to do this! I've also made up my own terms such as 'divisive_scalar' so don't bother googling
var divisive_scalar = (squared_horizontal_velocity / SQUARED_MAXIMUM_VELOCITY);
var divisive_scalar = ( 50 / 25 );
var divisive_scalar = 2;

var multiplicative_scalar = (divisive_scalar / (2*divisive_scalar));
var multiplicative_scalar = (2 / (2*2));
var multiplicative_scalar = (2 / 4);
var multiplicative_scalar = 0.5;

x_velocity = x_velocity * multiplicative_scalar
x_velocity = 5 * 0.5
x_velocity = 2.5

Ancora una volta, non riesco a capire perché sia ​​meglio, ma è più "unit-vector-y" perché multiplicative_scalar è un unit_vector? Come puoi vedere, uso parole come "unit-vector-y", quindi non sono un mago della matematica! Consapevole anche che i vettori di unità potrebbero non avere nulla a che fare con il teorema di Pitagora, quindi ignora tutto questo se sto abbaiando sull'albero sbagliato.

Sono una persona molto visiva (modellista 3D e concept artist di mestiere!) E trovo diagrammi e grafici davvero, davvero utili, per quanto più umanamente possibile, per favore!


2
In realtà, nessuno degli algoritmi scritti correttamente limita la velocità. Il vettore (2.5, 2.5)ha una magnitudine di circa 3,54, non di 5.
bcrist

1
sqrt(2.5*2.5 + 2.5*2.5)
bcrist

1
Noi no, il filosofo è morto 2.500 anni fa e il teorema che porta il suo nome è stato compreso da altre civiltà millenni prima ancora che nascesse. È un po 'come dire che usiamo Einstein nei sottomarini nucleari, un pensiero divertente di sicuro (ogni sub che ha un Einstein nell'equipaggio), ma quello che facciamo è applicare parte di una teoria che ha pubblicato. Nel caso di Einstein è famoso per molte teorie della fisica, quindi puoi nominare la teoria da cui deriva l'equivalenza energia-massa usando solo una parte del suo nome (ad esempio "relatività" invece di "relatività speciale") senza confonderla per un persona.
Andon M. Coleman,

3
Il problema con la tua posizione è l'affermazione che "possiamo fare la stessa cosa senza Pitagora". Ma la distanza di Manhattan non è la stessa della distanza euclidea, quindi stai confrontando mele e arance. Se si desidera distanza euclidea da una coppia di X / Y, è necessario fare i conti.
Jerry B,

3
correlate: "perché usiamo la matematica in fisica" e "perché usiamo la matematica nei giochi?"
vaxquis,

Risposte:


104

Il tuo codice privo di Pitagora non calcola una lunghezza come normalmente pensiamo.

Normalmente nei giochi 3D modelliamo il mondo come uno spazio euclideo e utilizziamo una metrica della distanza euclidea ( nota anche come teorema di Pitagora ) per calcolare la lunghezza totale di un vettore v con i componenti vx e vy Namely:

EuclideanLength(v) = sqrt(v.x * v.x + v.y * v.y)

(Si noti che questa radice quadrata manca nel codice di esempio sopra, motivo per cui i due approcci sembrano dare la stessa risposta. Di più su questo a breve ...)

Il codice che hai descritto utilizza la metrica della distanza di Manhattan :

ManhattanLength(v) = abs(v.x) + abs(v.y)

(Anche se non hai incluso i valori assoluti, il che potrebbe farlo comportare inaspettatamente per i numeri negativi)

È facile vedere che queste due funzioni di distanza coincidono quando vx o vy è zero e ci stiamo muovendo solo lungo un asse. Come si confrontano però quando ci muoviamo in diagonale?

Diciamo vx = vy = 1. Quanto è lungo questo vettore (equivalentemente, quanto è veloce la velocità che descrive)?

Euclidean                              Manhattan

sqrt(v.x*v.x + v.y * v.y)              abs(v.x) + abs(v.y)
sqrt(1 * 1 + 1 * 1)                    abs(1) + abs(1)
sqrt(2)                                1 + 1
1.414...                               2

Puoi vedere che queste metriche non sono effettivamente d'accordo per le linee diagonali.

Tracciamo su un grafico l'insieme di punti che ogni metrica afferma sono a una distanza di 1 dall'origine:

Metriche della distanza

La nostra familiare metrica euclidea è il cerchio rosso. Questo è l'insieme di tutti i punti x, y tale che x ^ 2 + y ^ 2 = 1. Puoi vedere che è simmetrico in senso rotazionale, ed è per questo che ci piace: rappresenta ordinatamente l'idea che la distanza non cambia con direzione.

La metrica di Manhattan è il diamante blu. Non è un ottimo abbinamento per la nostra idea intuitiva di distanza, ma non è male. In molti giochi basati su tessere in cui ti muovi in ​​passi discreti nelle quattro direzioni cardinali, la metrica di Manhattan fornisce la distanza corretta tra i punti (in termini di "quante mosse ci vorranno per arrivarci?")

Alla fine, ho usato la metrica di Chebyshev per divertimento - è il quadrato verde:

ChebyshevLength(v) = max(abs(v.x), abs(v.y))

È utile anche per i giochi basati su tessere, in cui è consentito spostarsi sulle diagonali. Un re negli scacchi si muove secondo la metrica di Chebyshev.

Spero che chiarisca quale sia la differenza tra il tipico codice in stile pitagorico e l'esempio che hai fornito sopra.


11

Senza Pitagora, sei legato a una velocità fissa su ciascun asse. Hai una velocità x, una velocità y e (in un mondo 3d) una velocità z che sono tutte indipendenti l'una dall'altra. Qualsiasi movimento sarà allineato a questi assi perpendicolari.

Tuttavia, con Pitagora, hai una velocità che può essere costante in qualsiasi angolo. Ciò consente di far scomparire la griglia e far muovere gli oggetti con una velocità costante in qualsiasi direzione possibile.

L'area che un oggetto percorre in un secondo appare così senza Pitagora (fe metrica di Chebyshev):

inserisci qui la descrizione dell'immagine

E questo con Pitagora:

inserisci qui la descrizione dell'immagine

Quest'ultimo di solito sembra molto più naturale in molti casi.

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.