2013-02-26 29 views
5

W aplikacji na Androida chcę narysować nogę. Aby wyprowadzić górną część nogi, robię coś takiego:Jak uzyskać matrycę, w której tłumaczę, a następnie obracam, a następnie tłumaczę, a następnie obracam po raz drugi?

// legCX,legCY is the location on screen about which the leg rotates. 
Matrix m = new Matrix(); 
m.postTranslate(-legCX,-legCY); 
m.postRotate(legRot); 
m.postTranslate(legCX,legCY); 

Następnie ustawiam matrycę na płótnie i narysuję nogę.

Jak narysować drugą część nogi poniżej kolana? Obraca się z inną prędkością niż noga nad nim i ma punkt środkowy, który porusza się z nogą nad nim. Próbowałem następujących rzeczy, ale okazało się, że końcowym rezultatem jest obrót wokół jakiegoś pojedynczego punktu, który nie podąża za nogą powyżej.

Matrix m = new Matrix(); 
m.postTranslate(-legCX,-legCY); 
m.postRotate(legRot); 
m.postTranslate(0,-legLength); 
m.postRotate(footRot); 
m.postTranslate(0,legLength); 
m.postTranslate(legCX,legCY); 

Podejrzewam, że jest to prawdopodobnie konieczne, aby wykonać dwa obroty w dwóch różnych obiektów Matrix a następnie połączyć je w jakiś sposób, ale nie mogę dowiedzieć się, jak dokładnie to zrobić.

EDIT: Ten typ macierzy wydaje się nazywać "macierzą transformacji". Łączenie wielu operacji nazywa się kompozycją przekształceń. Jednak żadna ze stron na ten temat nie wspomina, jak wykonać serię tłumaczeń i rotacji.

Oczywiście, jeśli można użyć macierzy do rotacji wokół jednego punktu, musi być możliwe wykonywanie wielu operacji macierzowych, aby umożliwić obrót o jeden punkt, a następnie dodatkowy obrót wokół innego punktu.

Próbowałem przeglądać strony poświęcone animacji szkieletu, ale nie potrafię zrozumieć, o czym mówią.

+0

Wygląda na to, że zapomniałeś cofnąć 'legRot'. Z wyjątkiem twojej najbardziej wewnętrznej rotacji wszystkie pozostałe operacje powinny być idealnie zrównoważone.Możesz to osiągnąć, dodając odwrotny obrót w odpowiedniej pozycji lub łącząc pierwsze trzy operacje w jedną macierz i stosując ją najpierw, a następnie odwrotnie. Jeśli to rozwiąże Twój problem, zmienię ten komentarz w odpowiedź. – MvG

+0

to nie działa. Chciałbym znaleźć poradnik, jak to zrobić, ale albo nie jest to możliwe, albo szukam niewłaściwej rzeczy. – HappyEngineer

Odpowiedz

6

Jeśli dobrze rozumiem Twój problem, masz przypadek względnej rotacji. Możesz spróbować wyszukać podwójne wahadło, patrz rys.

double pendulum

za pomocą macierzy rotacji nowe współrzędne punktu p1 obracana wokół punktu p0 można znaleźć jak

nowe współrzędne punktu p2 obracana wokół punktu p1 będzie

Wreszcie nowe współrzędne punktu p2 obracana wokół punktu p0 będzie

Zamówienie spraw mnożenia macierzy, jak również znak kątów.

+0

Wymyślam odpowiedź na gamedev. Nie jestem do końca pewien, czy ostateczne rozwiązanie, które tu znalazłem, odpowiada rzeczywistej matematyce, którą tu robisz. Nie wygląda na to, ale nie jestem do końca pewien, co robi obiekt Matrix. http://gamedev.stackexchange.com/questions/50171/what-matrix-operations-do-i-perform-to-translate-then-rotate-then-translate-then – HappyEngineer

2

Obawiam się, że będzie to agnostyk językowy - w tej chwili robię coś podobnego w systemie Android, ale uczę się zarówno androida, jak i matematyki macierzowej! Wydaje się, że wiesz jak używać macierzy w systemie Android, więc domyślam się, że to nie będzie problem.

Więc - załóżmy, że mamy dwie siatki (gdzie siatka jest tym, co można niezależnie rysować na ekranie): UpperLeg i LowerLeg.

  • Dla UpperLeg masz zamiar mieć punkt, w którym obraca się mesh (RotationPoint) (w realnym świecie to chyba byłoby hop) i masz zamiar mieć punkt, w którym przywiązuje się LowerLeg to (AttachmentPoint) (w realnym świecie myślę, że to byłoby kolano).
  • Dla LowerLeg będziesz miał punkt, w którym siatka obraca się (RotationPoint) (w realnym świecie, myślę, że to będzie kolano).

UpperLeg.AttachmentPoint =(w ten sposób twoja noga nie spadnie).

Załóżmy teraz wyobraź sobie, że masz dwie kwoty obrotu (jeden dla UpperLeg i jeden dla LowerLeg): UpperLeg.Rotation i LowerLeg.Rotation.

(One przedmiotem obrotu - jeśli nie słyszałeś o kwaterniony, należy spojrzeć - to mnie dziwi, że jakiś facet od 1846 roku wpadł na nich - w zasadzie enkapsulacji pojęcie obrotu, mogą być włączane do macierzy obrotowych, można łączyć (przez mnożenie) i nie cierpią z powodu blokady Gimbala).

Najpierw ty obracasz UpperLeg przez:

  1. Przesuwanie UpperLeg siatkę tak, że UpperLeg.RotationPoint jest pochodzenie
  2. Obrotowy przez UpperLeg.Rotation
  3. Przesuwanie UpperLeg siatkę tak, że jest tam, gdzie trzeba być w prawdziwym świecie. Widzę, że to robisz.

Tak dla LowerLeg byłoby:

  1. Przesuwanie LowerLeg siatkę tak, że LowerLeg.RotationPoint jest pochodzenie
  2. Obrotowy przez (UpperLeg.Rotation połączeniu z LowerLeg.Rotation)
  3. Przesuwanie LowerLeg przez siatkę taka sama ilość, jaką została przeniesiona siatka UpperLeg w kroku 3
  4. Przeniesienie LowerLeg siatki według wektora, który jest (wektor z UpperLeg.RotationPoint do UpperLeg.AttachmentPoint) obrócony o UpperLeg.Rotation.

Powyższe kroki można łączyć i optymalizować.

Zasadniczo mówię:
Obrót LowerLeg jak to musi być obracany, a następnie wpakować go tam, gdzie trzeba iść - gdzie musi przejść zostanie określona przez gdzie UpperLeg udał, a także w jaki sposób dostać się do miejsca, gdzie LowerLeg jest dołączony do UpperLeg.

To jest mój pierwszy wpis tutaj, więc jeśli złamałem jakieś zasady kardynalne, proszę daj mi znać, jakie one są.

Powiązane problemy