Benötige ich ein Point- und ein Vector-Objekt? Oder ist es in Ordnung, nur ein Vektorobjekt zur Darstellung eines Punkts zu verwenden?

18

Bei der Strukturierung der Komponenten eines Motors, die ich zusammen mit einem Freund entwickle (Lernzwecke), bin ich auf diesen Zweifel gestoßen.

Anfangs hatten wir einen Point-Konstruktor wie den folgenden:

var Point = function( x, y ) {
    this.x = x;
    this.y = y;
};

Aber sie haben begonnen, etwas Vektormathematik hinzuzufügen, und sie haben beschlossen, es in Vector2d umzubenennen.

Aber jetzt sind einige Methoden etwas verwirrend (zumindest meiner Meinung nach), wie zum Beispiel die folgende, die zum Erstellen einer Zeile verwendet wird:

//before the renaming of Point to Vector2, the parameters were startingPoint and endingPoint
Geometry.Line = function( startingVector, endingVector ) {
    //...
};

Ich sollte einen speziellen Konstruktor für das Point-Objekt erstellen, oder gibt es keine Probleme beim Definieren eines Punkts als Vektor?

Ich weiß, dass ein Vektor Größe und Richtung hat, aber ich sehe so viele Menschen, die einen Vektor verwenden, um nur die Position eines Objekts darzustellen.

JCM
quelle
1
Da die Position nur ein Vektor von (0,0 {, 0}) ist, kann ein Vektor verwendet werden.

Antworten:

8

Es ist unwahrscheinlich, dass es Probleme beim Zusammenführen der Definitionen und beim Behandeln von Punkten als Vektoren gibt - seien Sie jedoch vorsichtig, da einige APIs eine Point-Klasse haben, die Sie möglicherweise verwenden müssen (um z. B. Eckpunkte von Polygonen darzustellen), und wenn Wenn Sie Ihre eigene Klasse definieren, möchten Sie sie hin und her portieren können.

Ich würde sie jedoch in Ihrem Code gleich behandeln. Wenn Sie Vektor und Punkt austauschbar verwenden, gibt es keinen Grund, warum Ihre Deklaration für die Line () - Funktion von 'startingVector' und 'endingVector' sprechen sollte. Ich würde es sehr empfehlen, wieder dorthin zu gehen

Geometry.Line = function( Vector startingPoint, Vector endingPoint ) {
    //...
};

Diese Parameter stellen Punkte dar, auch wenn sie dazu die Klasse Vector verwenden.

Steven Stadnicki
quelle
Ich würde noch einen Schritt weiter gehen und typedef Vector Pointirgendwo in einem Header Punkte definieren. Auf diese Weise sieht es aus und fühlt sich an wie a Point, niemand kratzt sich am Kopf, wenn er es benutzt, warum es heißt, Vectoraber auf der internen Seite ist es nur eine Codebasis.
tpg2114
4

Verwenden Sie einfach das Vector-Objekt. Auch wenn Sie der Meinung sind, dass dies in der Vergangenheit falsch verwendet wurde / wurde, ist es das, was die Leute erwarten. Außerdem ist es nicht unbedingt falsch, einen Vektor als Punkt zu verwenden. Und wäre außerhalb der Diskussion schwierig zu tun, da beide Datenstrukturen die gleichen primitiven Typen erfordern. Die einzigen Unterschiede werden die Member-Funktionen sein, und es ist einfach genug, diese derselben Klasse zuzuordnen, da es zwischen den beiden Methoden keine großen Konflikte gibt.

Da Sie lernen, ist es gut zu lernen, dass das, was die Leute erwarten, oft der beste Weg ist, Dinge zu tun (für triviale Entscheidungen wie die, die präsentiert werden).

MichaelHouse
quelle
Die Elementfunktionen sind nicht der einzige Unterschied zwischen Punkten und Vektoren. So ist die wKomponente, die kritisch ist.
kevintodisco
3

Punkte sind Orte im Raum. Sobald Sie ein Koordinatensystem haben, können Sie diese Punkte als Abstand und Richtung vom Ursprung (einem Vektor) beschreiben. Es ist also durchaus sinnvoll, Vektoren zu verwenden, um den Anfangs- und Endpunkt einer Linie zu beschreiben.

Beachten Sie jedoch, dass alle Punkte als Vektor dargestellt werden können, Vektoren jedoch keine Punkte sind. Die meisten Vektoren, z. B. Geschwindigkeit, Normal usw., haben keinen Ortssinn.

Denken Sie an den Wind, Sie können über seine Richtung und Stärke sprechen, aber Sie können nicht über seine Position oder Position sprechen. So sollten Sie sich Vektoren vorstellen, wenn sie NICHT zur Beschreibung von Punkten im Raum verwendet werden.

Ken
quelle
2

Um einen Punkt zu definieren, benötigen Sie nur einen Vektor. Um eine Linie zu definieren, benötigen Sie zwei. Normalerweise haben Sie entweder zwei Punkte auf der Linie oder einen Vektor, der einen Punkt auf der Linie darstellt, und den anderen Vektor, der die Richtung der Linie darstellt.

Es gibt keine Probleme, einen Punkt als Vektor zu definieren, da ein Punkt ein Vektor ist, dessen Richtung gleich seinen Koordinaten und dessen Größe gleich seinem Abstand von 0,0 ist.

Sie brauchen also keine zwei getrennten Klassen, um einen Punkt und "Vector2d" darzustellen, obwohl ein Punkt vermutlich eine Unterklasse von Vector2d mit verschiedenen Elementfunktionen sein könnte, die in direktem Zusammenhang mit Ihrer Zeichnung oder Verarbeitung stehen, während Vector2d möglicherweise nur strenge vektormathematische Funktionen wie z dot Produkte.

Eric B
quelle
2

Ja, es ist in Ordnung, eine einzelne VectorKlasse zu verwenden, um sowohl Punkte als auch Vektoren zu definieren, solange Sie sicherstellen, dass die wKomponente des Vektors ist0 .

Der Schlüsselunterschied zwischen einem Punkt und einem Vektor ist , dass ein Punkt , eine physikalische Position im Raum darstellt, von dem Ursprung versetzt ist , während ein Vektor , der eine repräsentiert Richtung . Ein Punkt kann übersetzt werden, ein Vektor nicht . Die wKomponente einer 2- oder 3-dimensionalen VectorKlasse bewirkt, dass die Übersetzungskomponente einer Transformationsmatrix wirksam wird. Wenn wja 1, werden Translation und Rotation angewendet. Wenn dies der 0Fall ist , wird nur die Drehung angewendet.

Wenn Sie nicht über die wKomponente eines Vektorsatzes verfügen, 0kann dies Sie beißen. es führt zu Fehlern, die ziemlich schwer aufzuspüren sind. Um sicher zu sein, können Sie eine machen PointKlasse, die erbt von der VectorKlasse und explizit setzt wauf 1, wo die VectorKlasse Standardwerte wzu 0.

kevintodisco
quelle
2
Viele Vektorklassen verwenden die w-Komponente nicht explizit. Nicht wenige behandeln es als implizites Element oder haben eine Art 'ProjectiveVector'-Klasse, die es implementiert, aber so viel Code einer Engine (alles außerhalb des Renderns, im Wesentlichen) verwendet den' klassischen '3-Vektor, der eine aw-Komponente enthält ist völlig überflüssig. Dies ist ein Implementierungsdetail, kein wesentlicher Bestandteil von Vektoren oder Punkten.
Steven Stadnicki
@StevenStadnicki Das stimmt, aber damit eine Klasse sowohl einen Punkt als auch einen Vektor darstellt, wmuss die Komponente vorhanden sein. Andernfalls kann nicht festgelegt werden, wie das Objekt verwendet werden soll.
kevintodisco
1
@ktodisco Ich denke, die Art und Weise zu bestimmen, wie es verwendet werden soll, ist zu untersuchen, in welchem ​​Kontext es verwendet wird.
JCM
1
Lief die Zeit zum Bearbeiten des Kommentars aus :(. Wollte sagen, dass, wenn die Teile der Engine, die die Klasse verwenden, den Kontext definieren, in dem sie verwendet werden soll, es funktioniert.
kevintodisco
2

Punkte und Vektoren können als dasselbe betrachtet werden. Wenn es für Sie sinnvoll ist, können Sie sich Vektoren überlegen, die die Position auf diese Weise darstellen, und dann ist es logisch, eine Vector2Klasse überall dort zu verwenden , wo Sie sonst eine PointKlasse verwendet hätten.

In der Mathematik werden manchmal Vektoren verwendet, um die Position darzustellen. In diesem Sinne stellt der Vektor dar, wo sich eine Entität relativ zu einem Ursprungspunkt befindet. Angenommen, Sie machen einen Sh'mup und möchten verfolgen, wo sich das Schiff des Spielers im Spielbereich befindet. Wenn Sie die linke untere Ecke des Spielbereichs als (0, 0) behandeln, können Sie den Standort des Spielers mit einem Vector:

   * Player (3,3)
  /
 /
. (0,0)

Der Vektor bedeutet in diesem Fall, dass sich das Schiff 3 Einheiten rechts und 3 Einheiten über dem Ursprung befindet. (Beachten Sie, dass Sie auch einen Vektor für die Geschwindigkeit des Spielers verwenden können. In diesem Fall würde der Spieler 3 Einheiten nach rechts und 3 Einheiten nach oben pro Sekunde oder Frame verschieben. Sowohl Position als auch Geschwindigkeit würden durch dieselbe Vektorklasse dargestellt, aber ihre Vektoren würden anders im Skript des Spielers verarbeitet werden.)

Um Ihr Linienbeispiel zu verwenden, stellt der Positionsvektor dar, wo sich der Start- "Punkt" und der End- "Punkt" relativ zum Ursprung befinden. Wenn Ihr Ursprung in der Mitte des Spielbereichs liegt, können Sie eine Linie wie die folgende bestimmen:

             * (8, 2)
             |
     . (0,0) |
             |
             * (8, -2)

Ein Ende der Linie ist also 8 Einheiten rechts und 2 Einheiten über der Mitte des Spielfelds, und das andere ist 8 Einheiten rechts und 2 Einheiten nach unten.

Nur um klar zu sein, heißt das nicht, dass Sie eine VectorKlasse anstelle einer PointKlasse verwenden müssen. Dies ist nur eine Art, über diese Situation nachzudenken, die es einfacher machen kann, zu entscheiden, wie diese Ideen umgesetzt werden sollen.

Kevin - Setzen Sie Monica wieder ein
quelle
Der Vektor als Versatz zu einem anderen Punkt im Raum muss immer noch als Punkt in relativen Koordinaten betrachtet werden. Es als Vektor zu bezeichnen, ist in Bezug auf eine Spiel-Engine falsch.
kevintodisco
0

Das hängt von der Implementierung ab. Wenn Sie Methoden für den Vector2d anstelle seines Prototyps benötigen, fallen dafür Kosten an, wenn Sie die Anzahl der Punkte angeben, die Sie für ein Spiel benötigen, nämlich eine größere. So funktioniert JavaScript. In dieser Situation ist es besser, eine Point2d-Klasse zu erstellen, die nicht alle unnötigen Funktionen enthält.

dreta
quelle
Die Methoden werden zum Prototyp hinzugefügt, daher ist dies kein Problem.
JCM