Ho bisogno di un oggetto Point e Vector? O semplicemente usare un oggetto Vector per rappresentare un Punto va bene?


18

Strutturando i componenti di un motore che sto sviluppando insieme a un amico (scopi di apprendimento), sono giunto a questo dubbio.

Inizialmente avevamo un costruttore Point, come il seguente:

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

Ma loro abbiamo iniziato ad aggiungere un po 'di matematica Vector ad esso, e hanno deciso di rinominarlo in Vector2d.

Ma ora, alcuni metodi sono un po 'confusi (almeno secondo me), come il seguente, che viene utilizzato per fare una linea:

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

Dovrei creare un costruttore specifico per l'oggetto Point o non ci sono problemi nella definizione di un punto come vettore?

So che un vettore ha magnitudine e direzione, ma vedo così tante persone che usano un vettore per rappresentare la posizione di un oggetto.


1
Dato che la posizione è solo un vettore da (0,0 {, 0}), un vettore può essere usato bene.

Risposte:


8

È improbabile che ci siano problemi con la fusione delle definizioni e il trattamento dei punti come vettori - ma fai un po 'di attenzione, perché alcune API hanno una classe' Point 'che potresti dover usare (per rappresentare, ad esempio, vertici di poligoni) e se tu definisci la tua classe, vorrai essere in grado di portarli avanti e indietro.

Quello che vorrei fare, però, è trattarli in modo equivalente nel tuo codice; se usi il vettore e il punto in modo intercambiabile, allora non c'è motivo per cui la tua dichiarazione per la funzione Line () dovrebbe parlare di "startingVector" e "endingVector". Consiglio vivamente di tornare a

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

I punti rappresentano ciò che tali parametri rappresentano, anche se stanno usando la classe Vector per farlo.


Vorrei fare un ulteriore passo avanti e avere un punto typedef Vector Pointda qualche parte in un'intestazione che definisce i punti. In questo modo sembra e non sembra che Pointnessuno rimanga grattandosi la testa quando lo usa perché viene chiamato, Vectorma sul lato interno è solo una base di codice.
tpg2114,

4

Usa semplicemente l'oggetto Vector. Anche se ritieni che questo sia / sia stato usato in modo errato in passato, è quello che le persone si aspettano. Inoltre, non è necessariamente errato utilizzare un vettore come punto. E sarebbe difficile farlo al di fuori della discussione poiché entrambe le strutture di dati richiedono gli stessi tipi primitivi. Le uniche differenze saranno le funzioni membro, ed è abbastanza facile metterle nella stessa classe, poiché non c'è molto nel modo di metodi contrastanti tra i due.

Dal momento che stai imparando, è bene imparare che fare ciò che le persone si aspettano è spesso il modo migliore per fare le cose (per scelte insignificanti come quella presentata).


Le funzioni membro non sono l'unica differenza tra punti e vettori; così è il wcomponente, che è fondamentale.
kevintodisco,

3

I punti sono posizioni nello spazio. Una volta che hai un sistema di coordinate, puoi descrivere quei punti come una distanza e una direzione dall'origine (un vettore). Quindi è perfettamente ragionevole usare i vettori per descrivere i punti iniziale e finale di una linea.

Basta essere consapevoli del fatto che tutti i punti possono essere rappresentati come un vettore, ma i vettori non sono punti. La maggior parte dei vettori, ad esempio velocità, normale ecc., Non ha alcun senso della posizione.

Pensa al vento, puoi parlare della sua direzione e della sua forza, ma non puoi parlare della sua posizione o posizione. Ecco come dovresti pensare ai vettori quando NON vengono utilizzati per descrivere punti nello spazio.


2

Per definire un punto, è necessario un solo vettore. Per definire una linea, hai bisogno di due. In genere, hai due punti che si trovano sulla linea o un vettore che rappresenta un punto che si trova sulla linea e l'altro vettore che rappresenta la direzione della linea.

Non ci sono problemi a definire un punto come vettore, perché un punto È un vettore con direzione uguale alle sue coordinate e magnitudine uguale alla sua distanza da 0,0.

Quindi non sono necessarie due classi separate per rappresentare un punto e "Vector2d", sebbene un punto possa presumibilmente essere una sottoclasse di Vector2d con diverse funzioni membro direttamente correlate al disegno o all'elaborazione, mentre Vector2d potrebbe svolgere solo rigorose funzioni matematiche vettoriali come prodotti dot.


2

Sì, è possibile utilizzare una singola Vectorclasse per definire sia punti che vettori, purché si assicuri che sia il wcomponente del vettore0 .

La differenza chiave tra un punto e un vettore è che un punto rappresenta una posizione fisica nello spazio, spostato rispetto all'origine, mentre un vettore rappresenta una direzione . Un punto può essere tradotto, un vettore no . Il wcomponente di una Vectorclasse bidimensionale o tridimensionale è ciò che consente alla componente di traduzione di una matrice di trasformazione di avere effetto. Se wè 1, quindi verranno applicate traslazione e rotazione; se lo è 0, verrà applicata solo la rotazione.

Non avere il wcomponente di un set vettoriale 0può tornare a morderti; porta a bug che sono piuttosto difficili da rintracciare. Per essere sicuri, è possibile effettuare una Pointclasse che eredita dalla Vectorclasse e esplicitamente imposta wa 1, dove i Vectorvalori di default di classe wa 0.


2
Molte classi vettoriali non usano esplicitamente il componente w; alcuni lo trattano come un elemento implicito o hanno ciò che equivale a una classe "ProjectiveVector" che lo implementa, ma gran parte del codice di un motore (tutto al di fuori del rendering, in sostanza) utilizza il 3-vettore "classico" che porta in giro un componente aw è del tutto superfluo. Questo è un dettaglio di implementazione, non una parte essenziale di vettori o punti.
Steven Stadnicki,

@StevenStadnicki È vero, ma per avere una classe che rappresenti sia un punto che un vettore, il wcomponente deve essere presente, altrimenti non è possibile determinare come utilizzare l'oggetto.
kevintodisco,

1
@ktodisco Penso che il modo per determinare come dovrebbe essere usato, sta guardando in quale contesto viene utilizzato.
JCM,

1
È scaduto il tempo per modificare il commento :(. Stavo per dire che se le parti del motore che usano la classe definiscono il contesto in cui verrà utilizzato, allora funziona.
kevintodisco,

2

Punti e vettori possono essere pensati come la stessa cosa. Se per te ha senso, puoi pensare ai vettori che rappresentano la posizione in questo modo, e quindi è logico usare una Vector2classe ovunque che altrimenti avresti usato una Pointclasse.

In matematica, i vettori sono talvolta usati per rappresentare la posizione. Se utilizzato in questo senso, il vettore rappresenta la posizione di un'entità rispetto a un punto di origine. Ad esempio, supponi di fare uno sh'mup e di tenere traccia di dove si trova la nave del giocatore nell'area di gioco. Se tratti l'angolo in basso a sinistra dell'area di gioco come (0, 0), potresti rappresentare la posizione del giocatore con un Vector:

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

Il significato del vettore in questo caso è che la nave è 3 unità a destra e 3 unità sopra l'origine. (Nota che puoi anche usare un vettore per la velocità del giocatore, nel qual caso il giocatore dovrebbe spostare 3 unità a destra e 3 unità in alto ogni secondo o fotogramma. Sia la posizione che la velocità sarebbero rappresentate dalla stessa classe vettoriale, ma i loro vettori dovrebbero essere elaborato diversamente nella sceneggiatura del giocatore.)

Per usare l'esempio di linea, il vettore di posizione rappresenta la posizione in cui si trovano il "punto" iniziale e il "punto" finale rispetto all'origine. Se la tua origine è il centro dell'area di gioco, potresti determinare una linea come questa:

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

Quindi un'estremità della linea è 8 unità a destra e 2 unità sopra il centro del campo di gioco, e l'altra è 8 unità a destra e 2 unità in basso.

Giusto per essere chiari, questo non vuol dire che devi usare una Vectorclasse anziché una Pointclasse. Questo è solo un modo di pensare a questa situazione che può rendere più semplice decidere come implementare quelle idee.


Il vettore come offset di un altro punto nello spazio deve ancora essere considerato come un punto in coordinate relative. Chiamarlo vettore è sbagliato, per quanto riguarda un motore di gioco.
kevintodisco,

0

Dipende dall'implementazione. Se devi avere metodi su Vector2d invece che sul suo prototipo, allora c'è un costo per questo, data la quantità di punti di cui avresti bisogno in un gioco, uno importante. È proprio come funziona JavaScript. In quella situazione è meglio creare una classe Point2d che non abbia tutte le funzioni non necessarie.


I metodi vengono aggiunti al prototipo, quindi questo non è un problema.
JCM,
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.