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_VELOCITY
Konstante 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:
- Weniger Zeilen
- Innerhalb dieser Zeilen ist es einfacher zu lesen, was los ist
- ... 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!
quelle
(2.5, 2.5)
hat eine Größe von etwa 3,54, nicht 5.sqrt(2.5*2.5 + 2.5*2.5)
Antworten:
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.
(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 :
(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)?
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:
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:
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.
quelle
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:
Und das mit Pythagoras:
Letzteres erscheint in vielen Fällen viel natürlicher.
quelle