2010-07-28 20 views
7

Im próbuje zrobić prosty obrót sześcianu o xi osi y:OpenGL kwaterniony obrotu matryca

Chcę zawsze obracać sześcian nad osi x o kwotę x i obracać sześcian nad yAxis przez niezależny ilość y osi obrotu x

pierwszy naiwny tak:

glRotatef(x,1,0,0); 
glRotatef(y,0,1,0); 

następnie

ale że najpierw obraca OV er x następnie obraca się nad y Chcę obrócić nad y niezależnie od dostępu x.

zacząłem patrząc kwaterniony, więc próbowałem:

Quaternion Rotation1; 
Rotation1.createFromAxisAngle(0,1, 0, globalRotateY); 
Rotation1.normalize(); 

Quaternion Rotation2; 
Rotation2.createFromAxisAngle(1,0, 0, globalRotateX); 
Rotation2.normalize(); 

GLfloat Matrix[16]; 

Quaternion q=Rotation2 * Rotation1; 

q.createMatrix(Matrix); 
glMultMatrixf(Matrix); 

że właśnie robi prawie dokładnie to, co zostało osiągnięte robi 2 kolejne glRotates ... więc myślę, że im brakuje krok lub 2.

to jest kwaternictwo, czy powinienem użyć czegoś innego? ORAZ jeśli w kwaterach głównych chodzi o to, jakie kroki mogę dodać, aby kostka obracała się niezależnie od każdej osi. Myślę, że ktoś inny ma ten sam problem: Rotating OpenGL scene in 2 axes

+0

ok powiem to w ten sposób ... to, co chcę zrobić, to obracać sześcian za pomocą myszki. Chcę w lewo, aby kontrolować ekrany obrotu osi Y, a następnie w górę, aby sterować obrotami osi x ekranów. Chcę, aby obracały się niezależnie od innej osi, ale obracały się tylko na globalnej osi ekranu. Jeśli wykonam 2 glRotacje, nie otrzymam takiego zachowania, ponieważ obrót jednej osi mutlikuje drugi. – yeahdixon

+0

Na przykład obracanie kostki: żadne operacje obracania nie pokazują tylko jednej strony następnie robię glRotatef (90, 1, 0, 0); \t glRotatef (45,0,1,0); \t gives daje mi przechyloną kostkę (diament), gdy chcę sześcian, który miał swój narożnik skierowany w stronę kamery, który byłby faktycznie wynikiem zamiany operacji: \t glRotatef (45,0,1,0); \t glRotatef (90,1,0,0); Po prostu zamieniłabym polecenia rotacji, ale to działa na te same problemy, gdy wartości kątów są odwracane. – yeahdixon

Odpowiedz

3

Mam to do prawidłowego działania za pomocą kwaternionów: jestem pewien, że są inne sposoby, ale po pewnym reseatch, to działało idealnie dla mnie. Zamieściłem podobną wersję na innym forum.http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=280859&#Post280859

najpierw stworzyć reprezentację Kwaterniony kątów zmian X/Y czym każda ramka pomnożyć zmianę kątów quaternions do gromadzącego kwaterniony, wreszcie przekonwertować kwaternion do matrycy postaci pomnożyć aktualny matrycy. Oto główny kod pętli:

Quaternion3D Rotation1=Quaternion3DMakeWithAxisAndAngle(Vector3DMake(-1.0f,0,0), DEGREES_TO_RADIANS(globalRotateX)); 
Quaternion3DNormalize(&Rotation1); 

Quaternion3D Rotation2=Quaternion3DMakeWithAxisAndAngle(Vector3DMake(0.0f,-1.0f,0), DEGREES_TO_RADIANS(globalRotateY)); 
Quaternion3DNormalize(&Rotation2); 


Matrix3D Mat; 
Matrix3DSetIdentity(Mat); 
Quaternion3DMultiply(&QAccum, &Rotation1); 

Quaternion3DMultiply(&QAccum, &Rotation2); 

Matrix3DSetUsingQuaternion3D(Mat, QAccum); 
globalRotateX=0; 
globalRotateY=0; 

glMultMatrixf(Mat); 

następnie narysować sześcian

+0

Ta strona naprawdę pomogła: http://www.gamedev.net/reference/articles/article1095.asp ale początkowo nie miała sensu, dopóki nie zbadałam i nie próbowałam dalej – yeahdixon

0

Byłoby bardzo pomocne, jeśli mogłoby dać bardziej szczegółowe wyjaśnienie, co chce robić i jak wyniki są coraz różnią się od wyników, które chcesz. Ale generalnie używanie kątów Eulera do rotacji ma pewne problemy, ponieważ łączenie obrotów może prowadzić do nieintuicyjnego zachowania (aw najgorszym przypadku do utraty stopnia swobody).

Queternion slerp może być dla ciebie najlepszym sposobem, jeśli możesz znajdź pojedynczą oś i pojedynczy kąt, który reprezentuje pożądaną rotację. Ale wykonywanie kolejnych obrotów wokół osi X i Y za pomocą kwaternionów nie pomoże ci uniknąć problemów związanych z komponowaniem obrotów Eulera.

Opublikowany przez Ciebie wpis wydaje się jednak wymagać innego problemu. Wydaje się, że plakat tłumaczył jego obiekt, a następnie wykonywał jego obroty, kiedy powinien najpierw obracać się, a potem tłumaczyć.

+0

Opisałem powyższą kwestię bardziej szczegółowo, ale uważam, że oficjalnym terminem jest blokada kardana – yeahdixon

0

Nie jest jasne, co chcesz osiągnąć. Być może powinieneś pomyśleć o niektórych punktach i miejscach, w których chcesz je obracać - np. wierzchołek (1,1,1) powinien być odwzorowany (0,1,0). Następnie z tej informacji można obliczyć wymagany obrót.

Czwartorzędory są zwykle używane do interpolacji między dwoma obrotowymi "pozycjami". Zatem pierwszym krokiem jest zidentyfikowanie twoich początkowych i końcowych "pozycji", których jeszcze nie masz. Kiedy już to zrobisz, do interpolacji użyjesz kwaternionów. Nie brzmi to tak, jakbyś miał tutaj jakiś aspekt zmieniający się w czasie.

+0

Opisałem powyższy problem bardziej szczegółowo, ale uważam, że oficjalnym terminem jest blokada kardana – yeahdixon

0

Twój problem nie dotyczy blokady kardana. I faktycznie, nie ma powodu, dla którego twoja kwaternionowa wersja działałaby lepiej niż twoja wersja macierzy (glRotate), ponieważ używane przez ciebie kwaterunki są matematycznie identyczne z twoimi macierzami rotacyjnymi.

Jeśli chcesz kontrolować myszy, prawdopodobnie chcesz sprawdzić arcballs.

+0

dziękuję, tak, całkowicie się zgadzam, kwaternionów i matryc obrotowych mogą być wymieniane, więc można to zrobić bez kwaternionów. Odpowiedź na ten problem polegała bardziej na wstępnym multiplikowaniu matrycy przy użyciu przyrostowych obrotów. – yeahdixon