Czy potrzebuję obiektu Punkt i Wektor? Czy po prostu użycie obiektu Vector do przedstawienia punktu jest w porządku?

18

Konstruując elementy silnika, które rozwijam wraz z przyjacielem (w celach edukacyjnych), doszedłem do tej wątpliwości.

Początkowo mieliśmy konstruktora Point, jak poniżej:

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

Ale zaczęliśmy dodawać do niej trochę matematyki Vector i postanowili zmienić jej nazwę na Vector2d.

Ale teraz niektóre metody są nieco mylące (przynajmniej moim zdaniem), takie jak poniższe, które są używane do tworzenia linii:

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

Powinienem stworzyć konkretny konstruktor dla obiektu Point, czy nie ma żadnych problemów ze zdefiniowaniem punktu jako wektora?

Wiem, że wektor ma wielkość i kierunek, ale widzę, że tylu ludzi używa wektora do przedstawienia pozycji obiektu.

JCM
źródło
1
Ponieważ pozycja jest tylko wektorem z (0,0 {, 0}), wektor jest odpowiedni do użycia.

Odpowiedzi:

8

Jest mało prawdopodobne, aby wystąpiły jakiekolwiek problemy z łączeniem definicji i traktowaniem punktów jako wektorów - ale należy zachować ostrożność, ponieważ niektóre interfejsy API mają klasę „Point”, której może być konieczne (do reprezentowania np. Wierzchołków wielokątów) i jeśli jeśli zdefiniujesz własną klasę, będziesz chciał móc ją przenosić tam iz powrotem.

Co ja to zrobić, choć jest ich traktować równoważnie w kodzie; jeśli używasz wektora i punktu zamiennie, to nie ma powodu, aby twoja deklaracja dla funkcji Line () mówiła o „beginVector” i „endingVector”. Gorąco zachęcam do powrotu do

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

Punkty reprezentują te parametry, nawet jeśli używają do tego klasy Vector.

Steven Stadnicki
źródło
Chciałbym pójść o krok dalej i mieć typedef Vector Pointgdzieś w nagłówku, który określa punkty. W ten sposób wygląda i wydaje się Point, że nikt nie zdradza głowy, gdy używa się go, dlaczego się nazywa, Vectorale po wewnętrznej stronie jest to tylko jedna baza kodu.
tpg2114
4

Wystarczy użyć obiektu Vector. Nawet jeśli uważasz, że w przeszłości był / był używany nieprawidłowo, ludzie tego oczekują. Ponadto niekoniecznie jest niewłaściwe użycie wektora jako punktu. Byłoby to trudne poza dyskusją, ponieważ obie struktury danych wymagają tych samych prymitywnych typów. Jedynymi różnicami będą funkcje składowe i łatwo jest umieścić je w tej samej klasie, ponieważ między nimi nie ma wiele przeszkód.

Ponieważ uczysz się, dobrze jest dowiedzieć się, że robienie tego, czego oczekują ludzie, jest często najlepszym sposobem robienia rzeczy (w przypadku trywialnych wyborów, takich jak ten prezentowany).

MichaelHouse
źródło
Funkcje składowe nie są jedyną różnicą między punktami i wektorami; podobnie jest wkomponent, który jest krytyczny.
kevintodisco
3

Punkty to lokalizacje w kosmosie. Po uzyskaniu układu współrzędnych możesz opisać te punkty jako odległość i kierunek od początku (wektor). Jest więc całkowicie uzasadnione, aby użyć wektorów do opisania punktów początkowych i końcowych linii.

Pamiętaj tylko, że wszystkie punkty mogą być reprezentowane jako wektor, ale wektory nie są punktami. Większość wektorów, np. Prędkość, normalność itp., Nie ma żadnego poczucia lokalizacji.

Pomyśl o wietrze, możesz mówić o jego kierunku i sile, ale nie możesz mówić o jego położeniu ani położeniu. Tak powinniście myśleć o wektorach, gdy NIE są one używane do opisywania punktów w przestrzeni.

Rozpoznać
źródło
2

Aby zdefiniować punkt, potrzebujesz tylko jednego wektora. Aby zdefiniować linię, potrzebujesz dwóch. Zazwyczaj masz albo dwa punkty leżące na linii lub jeden wektor reprezentujący punkt leżący na linii, a drugi wektor reprezentujący kierunek linii.

Nie ma problemów ze zdefiniowaniem punktu jako wektora, ponieważ punkt JEST wektorem o kierunku równym jego współrzędnym i wielkości równej odległości od 0,0.

Nie potrzebujesz więc dwóch osobnych klas do reprezentowania punktu i „Vector2d”, chociaż Punkt może być prawdopodobnie podklasą Vector2d z różnymi funkcjami składowymi bezpośrednio związanymi z rysunkiem lub przetwarzaniem, podczas gdy Vector2d może wykonywać tylko ścisłe funkcje matematyczne wektorów, takie jak produkty kropkowe.

Eric B.
źródło
2

Tak, można użyć jednej Vectorklasy do zdefiniowania zarówno punktów, jakw0 i wektorów, o ile upewnisz się, że składową wektora jest .

Klucz różnica między punktem a wektora jest, że punkt reprezentuje fizyczną lokalizację w przestrzeni, odsunięcia od pochodzenia, podczas gdy wektor reprezentuje kierunek . Punkt można przetłumaczyć, wektor nie . wSkładnik 2- lub 3-wymiarowej Vectorklasy co umożliwia część translacyjną macierzy transformacji dla efektu odbioru. Jeśli wtak 1, zastosowane zostanie tłumaczenie i rotacja; jeśli tak 0, zastosowany zostanie tylko obrót.

Brak welementu zestawu wektorowego 0może cię ugryźć; prowadzi to do błędów, które są raczej trudne do wyśledzenia. Na wszelki wypadek można zrobić Pointklasę, która dziedziczy z Vectorklasy oraz wyraźnie określa wsię 1, gdzie Vectordomyślnie klasy wdo 0.

kevintodisco
źródło
2
Wiele klas wektorowych nie używa jawnie komponentu w; sporo osób traktuje go jako element niejawny lub ma coś, co stanowi klasę „ProjectiveVector”, która go implementuje, ale tak wiele kodu silnika (w zasadzie wszystko poza renderowaniem) używa „klasycznego” wektora 3, który przenosi komponent aw jest całkowicie zbędny. Jest to szczegół implementacji, a nie zasadnicza część wektorów lub punktów.
Steven Stadnicki
@StevenStadnicki To prawda, ale aby klasa reprezentowała zarówno punkt, jak i wektor, wkomponent musi być obecny, w przeciwnym razie nie ma sposobu na określenie, w jaki sposób obiekt powinien być używany.
kevintodisco
1
@ktodisco Myślę, że sposobem na określenie, jak należy go używać, jest sprawdzenie, w jakim kontekście jest on używany.
JCM
1
Skończył mi się czas na edycję komentarza :(. Chciałem powiedzieć, że jeśli części silnika, które używają klasy, określają kontekst, w którym będą używane, to działa.
kevintodisco
2

Punkty i wektory można traktować tak samo. Jeśli ma to dla ciebie sens, możesz pomyśleć o wektorach, które reprezentują pozycję w ten sposób, a następnie logiczne jest używanie Vector2klasy wszędzie tam, gdzie normalnie byś użył Pointklasy.

W matematyce wektory są czasami używane do reprezentowania pozycji. Użyty w tym sensie wektor reprezentuje lokalizację jakiegoś bytu względem punktu początkowego. Załóżmy na przykład, że robisz sh'mup i chcesz śledzić, gdzie statek gracza znajduje się w obszarze gry. Jeśli traktujesz lewy dolny róg obszaru gry jako (0, 0), możesz przedstawić lokalizację gracza za pomocą Vector:

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

W tym przypadku wektor oznacza, że ​​statek znajduje się 3 jednostki po prawej stronie i 3 jednostki powyżej miejsca początkowego. (Zauważ, że możesz również użyć wektora prędkości gracza, w którym to przypadku gracz przesunąłby 3 jednostki w prawo i 3 jednostki w górę co sekundę lub klatkę. Zarówno pozycja, jak i prędkość byłyby reprezentowane przez tę samą klasę wektorów, ale ich wektory byłyby przetwarzane inaczej w skrypcie gracza).

Aby użyć przykładu linii, wektor pozycji reprezentuje lokalizację początkowego „punktu” i końcowego „punktu” względem początku. Jeśli twoje pochodzenie jest centrum obszaru gry, możesz wyznaczyć taką linię:

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

Tak więc jeden koniec linii znajduje się 8 jednostek po prawej stronie i 2 jednostki powyżej środka pola gry, a drugi 8 jednostek po prawej i 2 jednostki w dół.

Żeby było jasne, nie oznacza to, że musisz użyć Vectorklasy zamiast Pointklasy. To tylko jeden sposób myślenia o tej sytuacji, który może ułatwić podjęcie decyzji, jak wdrożyć te pomysły.

Kevin - Przywróć Monikę
źródło
Wektor jako przesunięcie do innego punktu w przestrzeni wciąż należy traktować jako punkt we współrzędnych względnych. Nazywanie go wektorem jest błędne, jeśli chodzi o silnik gry.
kevintodisco
0

To zależy od wdrożenia. Jeśli musisz mieć metody na Vector2d zamiast jego prototypu, to wiąże się to z pewnym kosztem, biorąc pod uwagę liczbę punktów, których potrzebujesz w grze, głównej. Tak właśnie działa JavaScript. W takiej sytuacji lepiej jest utworzyć klasę Point2d, która nie ma wszystkich niepotrzebnych funkcji.

dreta
źródło
Metody są dodawane do prototypu, więc nie stanowi to problemu.
JCM,