Jestem programistą gier i nie studiowałem matematyki. Chcę tylko używać Quaternions jako narzędzia. Aby móc pracować z obrotem 3D, konieczne jest użycie Quaternions (lub Matryc, ale zatrzymajmy się w Quaternions tutaj w tym pytaniu). Myślę, że jest to ważne dla wielu programistów, aby z nich korzystać. Dlatego chcę podzielić się moją wiedzą i mam nadzieję wypełnić dziury, które mam. Teraz....
O ile rozumiem:
Quaternion może opisać 2 rzeczy:
- Obecna orientacja obiektu 3d.
- Transformacja obrotu, którą mógłby wykonać Obiekt. (rotationChange)
Możesz zrobić z Quaternion:
Multiplikacje:
Końcówka czwartorzędu = obrót czwartorzędu Zmień * Prąd czwartorzędu;
Na przykład: Mój obiekt 3D jest obrócony o 90 ° w lewo - a mój obrót zwielokrotniam to obrót o 180 ° w prawo, w końcu mój obiekt 3D jest obrócony w prawo.
Quaternion rotationChange = Quaternion endRotation * Quaternion.Inverse (startRotation);
Dzięki temu otrzymujesz opcję obrotuZmień, którą można zastosować do innej Orientacji.
Vector3 endPostion = Obrót czwartorzędu Zmień * Vector3 currentPosition;
Na przykład: Mój obiekt 3D jest w pozycji (0,0,0), a mój obrót zwielokrotniam to obrót o 180 ° w prawo, moja pozycja końcowa jest podobna (0, -50,0). Wewnątrz czwartorzędu znajduje się oś - i obrót wokół tej osi. Obracasz swój punkt wokół tej osi Y stopni.
Vector3 rotatedOffsetVector = Obrót czwartorzędu Zmień * Vector3 currentOffsetVector;
Na przykład: Mój kierunek startu pokazuje W GÓRĘ - (0,1,0), a mój obrót zwielokrotniam to obrót o 180 ° w prawo, mój kierunek końcowy jest skierowany w dół. (0, -1,0)
Mieszanie (Lerp i Slerp):
Quaternion currentOrientation = Quaternion.Slerp (startOrientation, endOrientation, interpolator)
jeśli interpolatorem jest 1: currentOrientation = endOrientation
jeśli interpolatorem jest 0: currentOrientation = startOrientation
Slerp interpoluje bardziej precyzyjnie, Lerp interpoluje bardziej wydajnie.
Moje pytania):
Czy wszystko, co wyjaśniłem do tej pory, jest prawidłowe?
Czy to „wszystko”, co możesz zrobić z Quaternions? (oczywiście nie)
Co jeszcze możesz z nimi zrobić?
Do czego służą produkty Dot i Cross między 2 czwartorzędami?
Edytować:
Zaktualizowano pytanie z kilkoma odpowiedziami
źródło
n
różne orientacje (postawy, pozy itp.). Następnie możesz je uśrednić za pomocą wag, skutecznie uogólniając slerp / lerp. Możesz także przekształcić ćwiartkę w wirnik, co jest równoważne zastosowaniu prędkości kątowej przez określony czas do sztywnego korpusu. Dlatego też można opisać całkowanie prędkości kątowej również z czwartorzędami. Możesz także oszacować, jak różne są dwie orientacje (obliczyć długość łuku rozpiętego przez dwa ćwiartki na hipersferze).Odpowiedzi:
Mnożenie
Przynajmniej jeśli chodzi o implementację Quaternions przez Unity, kolejność mnożenia opisana w pytaniu jest nieprawidłowa. Jest to ważne, ponieważ obrót 3D nie jest przemienny .
Tak więc, jeśli chcę obrócić obiekt,
rotationChange
zaczynając od jegocurrentOrientation
, zapisałbym go w następujący sposób:(tj. Transformacje układają się w górę w lewo - tak samo jak w konwencji macierzy Unity. Obrót w prawo jest stosowany najpierw / na „najbardziej lokalnym” końcu)
A gdybym chciał przekształcić kierunek lub wektor przesunięcia przez obrót, zapisałbym to w ten sposób:
(Unity wygeneruje błąd kompilacji, jeśli zrobisz coś przeciwnego)
Mieszanie
W większości przypadków można uniknąć rotacji Lerping. Wynika to z faktu, że kąt zastosowany „pod maską” w ćwiartce jest o połowę mniejszy od obrotu, co czyni go znacznie bliższym liniowemu przybliżeniu Lerpa niż coś w rodzaju Matrycy (która ogólnie nie będzie dobrze Lerpem!). Zapoznaj się z około 40 minutami tego filmu, aby uzyskać więcej wyjaśnień .
Jedynym przypadkiem, gdy naprawdę potrzebujesz Slerpa, jest to, że potrzebujesz stałej prędkości w czasie, na przykład interpolacji między klatkami kluczowymi na osi czasu animacji. W przypadkach, w których zależy ci tylko na tym, aby wynik był pośredni między dwoma wejściami (jak mieszanie warstw animacji), zwykle Lerp działa całkiem dobrze.
Co jeszcze?
Iloczyn skalarny dwóch kwaternionów jednostkowych daje cosinus kąta między nimi, dzięki czemu można korzystać z iloczynu skalarnego jako miara podobieństwa jeśli trzeba porównać obroty. Jest to jednak trochę niejasne, więc dla bardziej czytelnego kodu często używałbym Quaternion.Angle (a, b) , co wyraźniej wyraża, że porównujemy kąty w znanych jednostkach (stopniach).
Tego rodzaju metody wygody, które Unity zapewnia dla Quaternions, są bardzo przydatne. W prawie każdym projekcie używam tego co najmniej kilka razy :
Tworzy to kwaternion, który:
forward
argumentu wektorowegoup
argumentu wektorowego, jeśli jest podany, lub(0, 1, 0)
jeśli jest pominiętyPowodem, dla którego „wzrost” jest „jak najbliższy”, jest to, że system jest zawyżony. Stawianie
forward
czoła z + powoduje wykorzystanie dwóch stopni swobody (tj. Odchylenie i skok), więc mamy tylko jeden stopień swobody (przechylenie).Dość często szukam czegoś o przeciwnych właściwościach dokładności: chcę, aby lokalny y + wskazywał dokładnie wzdłuż
up
, a lokalny z + zbliżał się tak blisko, jak to możliweforward
z pozostałą swobodą.Pojawia się to na przykład podczas próby utworzenia ramki współrzędnych względem kamery do wprowadzania ruchu: chcę, aby mój lokalny kierunek w górę pozostawał prostopadły do podłogi lub nachylonej powierzchni normalnej, więc mój wkład nie próbuje tunelować postaci w teren lub lewitować ich z tego.
Możesz to również uzyskać, jeśli chcesz, aby obudowa wieży skierowana była w stronę celu, bez odrywania się od korpusu czołgu podczas celowania w górę / w dół.
W tym celu możemy zbudować naszą własną funkcję wygody, używając
LookRotation
do podnoszenia ciężkich przedmiotów:Tutaj najpierw obracamy lokalne y + do z +, a lokalne z + do y-.
Następnie obracamy nowe z + do naszego kierunku w górę (więc wynik netto to lokalne y + punkty bezpośrednio wzdłuż
exactUp
), a nowy y + jak najbliżej zanegowanego kierunku do przodu (więc wynik netto to lokalne punkty + + jak najbliżej)approximateForward
)Inną przydatną metodą wygody jest
Quaternion.RotateTowards
, z której często korzystam:To pozwala nam zbliżać się
targetRotation
ze stałą, kontrolowaną prędkością bez względu na liczbę klatek na sekundę - ważne dla rotacji, które wpływają na wynik / uczciwość mechaniki rozgrywki (np. Obracanie ruchu postaci lub śledzenie wieżyczki na graczu). Naiwny Lerping / Slerping w tej sytuacji może łatwo prowadzić do przypadków, w których ruch staje się szybszy przy wysokich prędkościach klatek, co wpływa na równowagę gry. (Nie oznacza to, że te metody są niewłaściwe - istnieją sposoby na ich prawidłowe użycie bez zmiany uczciwości, wymaga jedynie opieki.RotateTowards
Daje wygodny skrót, który się tym za nas opiekuje)źródło
Gdzie jest używany produkt kropkowy?
W Unity jednym z najczęstszych użytkowników produktu kropkowego jest za każdym razem, gdy sprawdzisz, czy dwa czwarte są równe przez
==
lub!=
. Unity oblicza iloczyn skalarny, aby sprawdzić podobieństwo zamiast bezpośrednio porównywać wewnętrzne wartości x, y, z, w. Warto o tym pamiętać, ponieważ powoduje to, że połączenie jest droższe, niż można się spodziewać.Używamy go również w ciekawym przypadku użycia ..
Zabawa z produktami kropek czwartorzędowych - sferyczne światy i orbitale
Coraz powszechniejsze stają się symulacje całych planet, a nawet całych układów słonecznych. Aby to zrobić w czasie rzeczywistym, potrzebujemy również produktu kropki czwartorzędu. Wiele z nich. Produkt kropki czwartorzędu jest bardzo słabo wykorzystywany, ale z pewnością ma swoje zastosowania - rzućmy okiem
Po pierwsze, mamy do rozważenia całą serię obrotów:
Połącz je wszystkie razem, a skończysz z dużą złożonością (i dużą liczbą!). Kiedy widz stoi na powierzchni planety, nie chcemy, aby pędzili z niesamowitą prędkością przez naszą przestrzeń świata gry. W rzeczywistości wolelibyśmy, aby były nieruchome i gdzieś w pobliżu źródła - zamiast tego przenieś wszechświat wokół gracza.
Co ważne, abyśmy w tym scenariuszu mogli uzyskać prawidłowy obrót i pochylenie planety, musimy zablokować biegun w osi, aby mógł on tylko przesuwać się w górę / w dół na powyższym obrazie (tj. Przesuwać „w górę” podczas podróży gracza północ). Właśnie tam pojawia się iloczyn czwartorzędowy. Gdybyśmy nie użyli iloczynu kropkowego i zamiast tego pomnożyli również nachylenie, to by się stało:
Zauważ, że bieguny naszych orbitujących „planet” zawsze przechylają się w kierunku gwiazdy. W rzeczywistości tak się nie dzieje - przechylenie jest ustalone .
Bez wchodzenia zbyt daleko w temat, oto krótkie podsumowanie:
Uzyskując tylko kąt, upuszczamy część tego niechcianego obrotu . W tym samym czasie zakończyliśmy również pomiar długości geograficznej, który jest przydatny do nawigacji, a także lokalnego klimatu.
* Planety są zbudowane z wielu komórek siatki . Wyświetlane są tylko te znajdujące się w pobliżu.
źródło
dot(a, b) = a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w
w przeciwieństwie do składu czwartorzędowego, którego użylibyśmy do połączenia rotacje) pomogłyby nam rozwiązać ten problem. Z przyjemnością głosuję, jeśli będziesz w stanie rozwinąć tę kwestię nieco później (nie mam na myśli powstrzymywania cię od skąpstwa ... Mam na myśli sen!)