Załóżmy, że piszesz kod macierzy, który obsługuje rotację, tłumaczenie itp. Dla przestrzeni 3D.
Teraz macierze transformacji muszą mieć 4x4, aby pasowały do komponentu tłumaczenia.
Jednak tak naprawdę nie musisz przechowywać w
komponentu w wektorze, prawda?
Nawet w podziale perspektywicznym można po prostu obliczać i przechowywać w
poza wektorem, a podział perspektywiczny przed powrotem z metody.
Na przykład:
// post multiply vec2=matrix*vector
Vector operator*( const Matrix & a, const Vector& v )
{
Vector r ;
// do matrix mult
r.x = a._11*v.x + a._12*v.y ...
real w = a._41*v.x + a._42*v.y ...
// perspective divide
r /= w ;
return r ;
}
Czy warto przechowywać w
w klasie Vector?
mathematics
vector
projection
Bobobobo
źródło
źródło
r.x = ... + a._14*v.w;
r.y = ... + a._24*v.w;
r.z = ... + a._34*v.w;
r.w = ... + a._44*v.w;
spójrz na moją odpowiedź, aby poznać szczegółyOdpowiedzi:
EDIT Disclaimer : Dla wygody w tej odpowiedzi wektory o w == 0 są nazywane wektorami, a w = = 1 są nazywane punktami. Chociaż, jak wskazał FxIII, nie jest to matematycznie poprawna terminologia. Ponieważ jednak odpowiedzią nie jest terminologia, ale potrzeba rozróżnienia obu typów wektorów, będę się jej trzymać. Ze względów praktycznych konwencja ta jest szeroko stosowana w tworzeniu gier.
Niemożliwe jest rozróżnienie wektorów i punktów bez komponentu „w”. Wynosi 1 dla punktów i 0 dla wektorów.
Jeśli wektory zostaną pomnożone przez macierz transformacji afinicznej 4x4, która ma translację w swoim ostatnim wierszu / kolumnie, wektor również zostałby przetłumaczony, co jest błędne, muszą zostać przetłumaczone tylko punkty. Zajmuje się tym zero w składniku „w” wektora.
Podkreślenie tej części mnożenia macierzy i wektora czyni jaśniej:
Tzn. Źle byłoby przetłumaczyć wektor, na przykład oś obrotu, wynik jest po prostu zły. Mając czwarty składnik zerowy, nadal możesz użyć tej samej macierzy, która przekształca punkty, aby przekształcić oś obrotu, a wynik będzie ważny a jego długość jest zachowana, dopóki matryca nie ma skali. Takie zachowanie chcesz dla wektorów. Bez czwartego komponentu musielibyśmy utworzyć 2 macierze (lub 2 różne funkcje mnożenia z niejawnym czwartym parametrem.) I wykonać 2 różne wywołania funkcji dla punktów i wektorów.
Aby użyć rejestrów wektorowych współczesnych procesorów (SSE, Altivec, SPU), musisz przekazać 4x 32-bitowe zmiennoprzecinkowe (jest to rejestr 128-bitowy), a ponadto musisz zadbać o wyrównanie, zwykle 16 bajtów. Więc i tak nie masz szansy zabezpieczyć miejsca dla czwartego komponentu.
EDYCJA: Odpowiedź na pytanie jest w zasadzie
Trzeba wybrać jedną z nich, nie można zapisać tylko {x, y, z} i nadal używać tylko jednej funkcji mnożenia macierzy-wektora. XNA na przykład wykorzystuje to drugie podejście, mając 2 funkcje transformacji w swojej klasie Vector3 o nazwie
Transform
iTransformNormal
Oto przykład kodu, który pokazuje oba podejścia i pokazuje potrzebę rozróżnienia obu rodzajów wektorów na 1 z 2 możliwych sposobów. Poruszamy byt gry o pozycji i kierunku patrzenia w świecie, przekształcając go za pomocą matrycy. Jeśli nie użyjemy komponentu „w”, nie będziemy już mogli używać tego samego mnożenia macierzy i wektora, jak pokazuje ten przykład. Jeśli i tak to zrobimy, otrzymamy złą odpowiedź na transformowany
look_dir
wektor:Stan jednostki początkowej:
Teraz transformacja z translacją x + 5 i obrotem o 90 stopni wokół osi y zostanie zastosowana do tego elementu. Prawidłowa odpowiedź po transformacji to:
Poprawną odpowiedź otrzymamy tylko wtedy, gdy rozróżnimy wektory o == 0 i pozycje o = = 1 na jeden z powyższych sposobów.
źródło
Jeśli tworzysz klasę Vector, zakładam, że klasa będzie przechowywać opis wektora 3D. Wektory 3D mają wielkości x, y i z. Więc jeśli twój wektor nie potrzebuje dowolnej wielkości w, nie, nie będziesz go przechowywać w klasie.
Istnieje duża różnica między wektorem a macierzą transformacji. Biorąc pod uwagę, że zarówno DirectX, jak i OpenGL zajmują się macierzami dla ciebie, zwykle nie przechowuję macierzy 4x4 w moim kodzie; raczej przechowuję rotacje Eulera (lub Quaternions, jeśli chcesz - które przypadkowo mają komponent aw) i tłumaczenie x, y, z. Translacja jest wektorem, jeśli chcesz, a obrót technicznie pasowałby również do wektora, w którym każdy komponent przechowywałby wielkość obrotu wokół swojej osi.
Jeśli chcesz nurkować nieco głębiej w matematyce wektora, wektor euklidesowy jest tylko kierunkiem i wielkością. Zwykle jest to reprezentowane przez triplet liczb, gdzie każda liczba jest wielkością wzdłuż osi; jego kierunek jest implikowany przez połączenie tych trzech wielkości, a wielkość można znaleźć za pomocą wzoru euklidesowego na odległość . Lub czasami tak naprawdę jest przechowywany jako kierunek (wektor o długości = 1) i wielkość (liczba zmiennoprzecinkowa), jeśli to jest wygodne (np. Jeśli wielkość zmienia się częściej niż kierunek, wygodniej jest po prostu zmień tę liczbę jasności niż weź wektor, normalizuj go i pomnóż składniki przez nową jasność).
źródło
Czwarty wymiar w wektorze 3D służy do obliczania przekształceń afinicznych, których obliczenie przy użyciu samych macierzy będzie niemożliwe. Przestrzeń pozostaje trójwymiarowa, więc oznacza to, że czwarty jest w jakiś sposób odwzorowany w przestrzeni 3d.
Mapowanie wymiarów oznacza, że różne wektory 4D wskazują ten sam punkt 3D. Mapa jest taka, że jeśli A = [x ', y', z'.w '] i B = [x ", y", z ", w"] reprezentują ten sam punkt, jeśli x' / x "= y ' / y "= z '/ z" = w' / w "= α tzn. składnik jest proporcjonalny dla tego samego współczynnika α.
Powiedział, że możesz wyrazić punkt - powiedzmy (1,3,7) - w nieskończony sposób, jak (1,3,7,1) lub (2,6,14,2) lub (131 393 917 131) lub ogólnie (α · 1, α · 3, α · 7, α).
Oznacza to, że można przeskalować wektor 4D do innego reprezentującego ten sam punkt 3D, aby w = 1: forma (x, y, z, 1) była formą kanoniczną.
Kiedy zastosujesz macierz do tego wektora, możesz otrzymać wektor, który nie ma w = 1, ale zawsze możesz skalować wyniki, aby zapisać je w formie kanonicznej. Wydaje się więc, że odpowiedź brzmi „powinieneś używać wektorów 4D podczas matematyki, ale nie przechowuj czwartego elementu” .
Jest to całkiem prawda, ale są pewne punkty, których nie można ułożyć w formie kanonicznej: punkty takie jak (4,2,5,0). Te punkty są specjalne, reprezentują skierowany nieskończony punkt i mogą być konsekwentnie normalizowane do wektora jednostkowego: możesz bezpiecznie przejść do nieskończoności i powrócić (nawet dwukrotnie) bez bycia Chuckiem Norrisem. Otrzymasz żałosny podział na zero, jeśli spróbujesz wymusić te wektory w formie kanonicznej.
Teraz już wiesz, więc wybór należy do Ciebie!
źródło
Tak Twoja transformacja jest nieprawidłowa dla niektórych rodzajów wektorów. Widać to w bibliotece matematycznej D3DX - mają dwie różne funkcje mnożenia macierzy i wektora, jedną dla w = 0 i jedną dla w = 1.
źródło
Zależy od tego, czego chcesz i potrzebujesz. :)
Zapisałbym to, b / c jest to konieczne do transformacji i tak dalej (nie można pomnożyć 3 wektorów z macierzą 4x4), chociaż jeśli zawsze masz aw 1, myślę, że możesz to po prostu sfałszować.
źródło