2009-10-12 14 views
14

Zasadniczo, biorąc pod uwagę quaterion (qx, qy, qz, qw) ... Jak mogę to przekonwertować na macierz rotacji OpenGL? Interesuje mnie również, który wiersz macierzy jest "Up", "Right", "Forward" itd ... Mam rotację kamery w kwaternionu, której potrzebuję w wektorach ...Konwertuj kwaternionowy obrót do macierzy obrotu?

Odpowiedz

27

Poniższy kod jest oparty na kwaterniony (qw, qx, QY, QZ), jeżeli zlecenie jest oparta na kwaterniony Boost:

boost::math::quaternion<float> quaternion; 
float qw = quaternion.R_component_1(); 
float qx = quaternion.R_component_2(); 
float qy = quaternion.R_component_3(); 
float qz = quaternion.R_component_4(); 

Najpierw trzeba znormalizować kwaternion:

const float n = 1.0f/sqrt(qx*qx+qy*qy+qz*qz+qw*qw); 
qx *= n; 
qy *= n; 
qz *= n; 
qw *= n; 

Następnie można utworzyć y nasza macierz:

Matrix<float, 4>(
    1.0f - 2.0f*qy*qy - 2.0f*qz*qz, 2.0f*qx*qy - 2.0f*qz*qw, 2.0f*qx*qz + 2.0f*qy*qw, 0.0f, 
    2.0f*qx*qy + 2.0f*qz*qw, 1.0f - 2.0f*qx*qx - 2.0f*qz*qz, 2.0f*qy*qz - 2.0f*qx*qw, 0.0f, 
    2.0f*qx*qz - 2.0f*qy*qw, 2.0f*qy*qz + 2.0f*qx*qw, 1.0f - 2.0f*qx*qx - 2.0f*qy*qy, 0.0f, 
    0.0f, 0.0f, 0.0f, 1.0f); 

W zależności od klasy macierzy może być konieczne jej przeniesienie przed przekazaniem do OpenGL.

+0

fyi this wygląda jak wielka interpretacja dla każdego, kto na to patrzy. Powinno działać tak, jak przy przechodzeniu do OpenGL, ponieważ wynik kolumna-major i wiersz-główna w tej samej macierzy liniowej. Jeśli jednak użyjesz tego z biblioteką typu kolumna do zwielokrotnienia z inną macierzą, możesz uzyskać problemy w zależności od działania twojej biblioteki. – johnbakers

+0

Nice. Więc doładowanie może zrobić prawie wszystko, co znajduję. –

+0

Zobacz także: http://stackoverflow.com/questions/1274936/flipping-a-quaternion-od-right-to-left-handed-coordianates, które wspominają, że kwaternionowie NIE mają ręki, ale to matryce DO. Być może będziesz musiał zmodyfikować 6 komórek powyższej transformacji, łącząc je w sort. Komórki 21,31,32,12,13,23. (Poza tym, właśnie wkleiłem ten kod i zmieniłem trochę dla mojej konkretnej biblioteki, i zadziałało świetnie. Dzięki!) –

9

Jeden sposób, aby to zrobić, co jest dość łatwe do wizualizacji, to zastosowanie obrotu określonego przez twój kwaternion do wektorów bazowych (1,0,0), (0,1,0) i (0,0,1). Obrócone wartości dają wektory bazowe w systemie obrotowym w stosunku do pierwotnego układu. Użyj wektorów , aby utworzyć rzędy macierzy obrotu. Wynikowa macierz i jej transpozycja, , przedstawiają przekształcenie do przodu i odwrotnie między oryginalnym układem a obróconym układem .

nie jestem zaznajomiony z konwencji stosowanych przez OpenGL, więc może ktoś inny może odpowiedzieć że części pytania ...

+0

Tak zapomniałem mogę to zrobić ... dam mu iść – Polaris878

+0

matematycznie poprawne, ale obliczeniowo więcej drogie, aby to zrobić w ten sposób. – teodron

+0

Testowałem to, ponieważ ta wersja używa instrukcji, że niektóre urządzenia (konkretnie myślę o shaderów GPU) mogą być specjalnie zoptymalizowane, więc prawdopodobnie nie byłbym pewien, czy jest to bardziej kosztowne obliczeniowo ... –

3

Być może nie musisz w ogóle zajmować się macierzą obrotu. Tutaj jest sposób, który wydaje się być szybsza niż konwersja do matrycy i mnożenie wektorowe ze sobą:

// move vector to camera position co (before or after rotation depending on the goal) 
    v -= co; 

    // rotate vector v by quaternion q; see info [1] 
    vec3 t = 2 * cross(q.xyz, v); 
    v = v + q.w * t + cross(q.xyz, t); 

[1] http://mollyrocket.com/forums/viewtopic.php?t=833&sid=3a84e00a70ccb046cfc87ac39881a3d0

+0

Link nie działa. – Dan

0

pomocą GLM, wystarczy użyć proces odlewania. więc przekonwertować z matrix4 do kwaterniony, wystarczy napisać

GLM :: mat4_cast (quaternion_name)

Powiązane problemy