Warum verwenden wir den Satz von Pythagoras in der Spielphysik?

38

Ich habe kürzlich erfahren, dass wir in unseren physikalischen Berechnungen häufig den Satz von Pythagoras verwenden, und ich fürchte, ich verstehe den Punkt nicht wirklich.

Hier ist ein Beispiel aus einem Buch , um sicherzustellen, dass ein Objekt nicht schneller als eine MAXIMUM_VELOCITYKonstante in der horizontalen Ebene wandert:

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;
    }
}

Versuchen wir das mit ein paar Zahlen:

Ein Objekt versucht, 5 Einheiten in x und 5 Einheiten in z zu verschieben. Es sollten sich insgesamt nur 5 Einheiten horizontal bewegen lassen!

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
    }
}

Das funktioniert jetzt gut, aber wir können dasselbe auch ohne Pythagoras machen:

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
    }
}

Vorteile ohne Pythagoras:

  1. Weniger Zeilen
  2. Innerhalb dieser Zeilen ist es einfacher zu lesen, was los ist
  3. ... und die Berechnung nimmt weniger Zeit in Anspruch, da es weniger Multiplikationen gibt

Mir kommt es so vor, als würden Computer und Menschen ohne den Satz von Pythagoras ein besseres Geschäft machen! Ich bin mir jedoch sicher, dass ich mich geirrt habe, da ich den Satz von Pythagoras an einer Reihe angesehener Orte gesehen habe. Deshalb möchte ich, dass mir jemand erklärt, welchen Vorteil es hat, den Satz von Pythagoras bei einem Mathematik- Neuling anzuwenden .

Hat dies etwas mit Einheitsvektoren zu tun? Für mich ist ein Einheitsvektor, wenn wir einen Vektor normalisieren und ihn in einen Bruchteil umwandeln. Wir tun dies, indem wir den Vektor durch eine größere Konstante teilen. Ich bin mir nicht sicher, welche Konstante es ist. Die Gesamtgröße des Graphen? Wie auch immer, da es sich um einen Bruch handelt, ist ein Einheitsvektor im Grunde genommen ein Graph, der in ein 3D-Gitter passen kann, wobei die x-Achse von -1 nach 1, die z-Achse von -1 nach 1 und die y-Achse verlaufen -Achse läuft von -1 bis 1. Das ist buchstäblich alles, was ich über Einheitsvektoren weiß ... nicht viel: P Und ich verstehe ihre Nützlichkeit nicht.

Außerdem erstellen wir in den obigen Beispielen keinen Einheitsvektor. Soll ich den Skalar so bestimmen:

// 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

Ich kann wieder nicht verstehen, warum dies besser ist, aber es ist mehr "Einheitsvektor-y", weil der multiplikative_Skalar ein Einheitsvektor ist. Wie Sie sehen können, verwende ich Wörter wie "unit-vector-y", also bin ich wirklich kein Mathematik-Zauberer! Beachten Sie auch, dass Einheitsvektoren möglicherweise nichts mit dem Satz von Pythagoras zu tun haben. Ignorieren Sie all dies, wenn ich den falschen Baum anklopfe.

Ich bin eine sehr visuelle Person (3D-Modellbauer und Konzeptkünstler von Beruf!) Und ich finde Diagramme und Grafiken wirklich sehr, sehr hilfreich, so viele wie nur irgend möglich, bitte!

Starkers
quelle
2
Tatsächlich begrenzt keiner der Algorithmen, wie sie korrekt geschrieben wurden, die Geschwindigkeit. Der Vektor (2.5, 2.5)hat eine Größe von etwa 3,54, nicht 5.
bcrist
1
sqrt(2.5*2.5 + 2.5*2.5)
bcrist
1
Wir nicht, der Philosoph starb vor 2.500 Jahren und der Satz, der seinen Namen trägt, wurde von anderen Zivilisationen Jahrtausende vor seiner Geburt verstanden. Das ist ein bisschen so, als würden wir Einstein in Neuclear-U-Booten verwenden, ein lustiger Gedanke (jedes U-Boot hat einen Einstein in der Crew), aber wir wenden Teil einer Theorie an, die er veröffentlicht hat. Im Fall von Einstein ist er für viele Theorien in der Physik berühmt, so dass Sie die Theorie, aus der die Massen-Energie-Äquivalenz abgeleitet wird, nur mit einem Teil ihres Namens benennen können (z. B. "Relativitätstheorie" anstelle von "Spezielle Relativitätstheorie"), ohne sie für eine zu verwechseln Person.
Andon M. Coleman
3
Das Problem mit Ihrer Position ist die Behauptung, dass "wir dasselbe ohne Pythagoras tun können". Aber die Entfernung von Manhattan entspricht nicht der Entfernung von Euklidian. Sie vergleichen also Äpfel und Apfelsinen. Wenn Sie einen euklidischen Abstand von einem X / Y-Paar wünschen, müssen Sie die Mathematik durchführen.
Jerry B
3
verwandt: "warum benutzen wir Mathe in der Physik" und "warum benutzen wir Mathe in Spielen?"
Vaxquis

Antworten:

104

Ihr Pythagoras-freier Code berechnet keine Länge, wie wir es normalerweise denken.

Normalerweise modellieren wir in 3D-Spielen die Welt als euklidischen Raum und verwenden eine euklidische Distanzmetrik ( auch bekannt als Pythagoras-Theorem ), um die Gesamtlänge eines Vektors v mit den Komponenten vx und vy zu berechnen.

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

(Beachten Sie, dass diese Quadratwurzel in Ihrem obigen Beispielcode fehlt, weshalb die beiden Ansätze scheinbar dieselbe Antwort geben. Mehr dazu in Kürze ...)

Der von Ihnen beschriebene Code verwendet die Manhattan-Entfernungsmetrik :

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

(Obwohl Sie die absoluten Werte nicht angegeben haben, kann dies zu unerwartetem Verhalten bei negativen Zahlen führen.)

Es ist leicht zu erkennen, dass diese beiden Abstandsfunktionen übereinstimmen, wenn vx oder vy Null ist und wir uns nur entlang einer Achse bewegen. Wie vergleichen sie sich aber, wenn wir uns diagonal bewegen?

Sagen wir vx = vy = 1. Wie lang ist dieser Vektor (äquivalent dazu, wie schnell ist die Geschwindigkeit, die er beschreibt)?

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

Sie können sehen, dass diese Metriken für diagonale Linien nicht übereinstimmen.

Zeichnen wir in einem Diagramm die Punktmenge, von der jede Metrik sagt, dass sie einen Abstand von 1 vom Ursprung entfernt ist:

Entfernungsmetriken

Unsere bekannte euklidische Metrik ist der rote Kreis. Dies ist die Menge aller Punkte x, y, so dass x ^ 2 + y ^ 2 = 1. Sie können sehen, dass es rotationssymmetrisch ist, und deshalb gefällt es uns: Es repräsentiert genau die Idee, dass sich der Abstand nicht mit ändert Richtung.

Die Manhattan-Metrik ist der blaue Diamant. Keine gute Übereinstimmung mit unserer intuitiven Vorstellung von Distanz - aber das macht es nicht schlimm. In vielen auf Kacheln basierenden Spielen, in denen Sie sich in diskreten Schritten in die vier Hauptrichtungen bewegen, gibt die Manhattan-Metrik den richtigen Abstand zwischen den Punkten an (in Bezug auf "Wie viele Züge werden benötigt, um dorthin zu gelangen?").

Schließlich habe ich zum Spaß die Chebyshev-Metrik eingegeben - es ist das grüne Quadrat:

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

Es ist auch gut für Spiele auf Kacheln, bei denen Sie sich auf Diagonalen bewegen dürfen. Ein König im Schach bewegt sich nach der Chebyshev-Metrik.

Ich hoffe, das verdeutlicht den Unterschied zwischen dem typischen pythagoreischen Code und dem obigen Beispiel.

DMGregory
quelle
11

Ohne Pythagoras sind Sie auf jeder Achse an eine feste Geschwindigkeit gebunden. Sie haben eine X-Geschwindigkeit, eine Y-Geschwindigkeit und (in einer 3D-Welt) eine Z-Geschwindigkeit, die alle unabhängig voneinander sind. Jede Bewegung wird auf diese senkrechte Achse ausgerichtet.

Mit Pythagoras haben Sie jedoch eine Geschwindigkeit, die in jedem Winkel konstant sein kann. Auf diese Weise können Sie das Raster verschwinden lassen und Objekte mit einer konstanten Geschwindigkeit in jede mögliche Richtung bewegen.

Die Fläche, die ein Objekt in einer Sekunde zurücklegt, sieht ohne Pythagoras (z. B. Chebyshev-Metrik) so aus:

Bildbeschreibung hier eingeben

Und das mit Pythagoras:

Bildbeschreibung hier eingeben

Letzteres erscheint in vielen Fällen viel natürlicher.

Philipp
quelle