2009-12-09 13 views
6

Próbuję zaimplementować rotację za pomocą arcball/trackballa, ale mam problem z obrotem środka . Chcę, aby centrum było centrum mojego ekranu bez względu na wszystko.Jak obracać się wokół środka ekranu za pomocą kwaternionów w opengl?

Pozwól mi wyjaśnić, co zrobiłem do tej pory.

Utworzona quaterion (oś obrotowa: vector_start x vector_end przy kącie vector_start * vector_end)

Z tego kwaterniony Utworzona macierz obrotu w celu wykorzystania go glMultMatrixf (Matrix) i uzyskać pożądany obrót.

Problem polega na tym, że podczas gdy mój model wydaje się obracać tak, jak powinien, zawsze obraca się wokół swojego lokalnego pochodzenia. Jak mogę go obrócić wokół środka ekranu? Nie ważne, gdzie znajduje się jego lokalne pochodzenie?

Przypuszczam, że rozwiązaniem tego problemu może być przetłumaczenie całej osi obrotu na środku ekranu, a następnie zastosowanie obrotu, ale czy jest to możliwe? Czy tęsknię za czymś tutaj?

Odpowiedz

1

Powinieneś być w stanie rozwiązać ten problem, stosując macierze rotacyjne i translacyjne w prawidłowej kolejności. W swoim kodzie możesz przetłumaczyć z powrotem na miejsce pochodzenia T (-pos_x, -pos_y, -pos_z), zastosować rotację i ponownie przetłumaczyć na centrum obiektowym T (pos_x, pos_y, pos_z). Powinno to działać ogólnie, niezależnie od konstrukcji macierzy rotacyjnej.

+0

Tak, ale gdy zastosuję glMultMatrixf() nie opengl obraca model wokół jego lokalnego pochodzenia? Więc jeśli przetłumaczyć na początek obrotu (nie za pomocą glRotatef(), ale glMultMatrix()), a następnie przetłumaczyć z powrotem mój model będzie obracany ponownie wokół jego pochodzenia, a nie tak, jakby jego pochodzenie było na przykład środkiem ekranu. –

+0

Przetłumacz z glTranslatef(), a następnie pomnóż z macierzą rotacji glMultMatrix() i ponownie przetłumaczyć za pomocą glTranslatef(). To w przeciwieństwie do zwykłego wywoływania glMultMatrix(). To nie działa? – catchmeifyoutry

+0

Nie, to nie działa. To, co robi, polega na tym, że obraca model zgodnie z informacją od macierzy rotacji stosowanej przez glMultMatrixf, ale wokół jej lokalnego pochodzenia. Próbowałem przekonwertować kwaternion obrotu na kątów Eulera, a następnie zastosować glRotatef (Yaw, 0., 0., 1.); glRotatef (Pich, 0., 1., 0.); glRotatef (Roll, 1., 0., 0.); zamiast bezpośrednio zastosować glMultMatrixf(), ale wtedy, gdy obrót był mniej więcej pośrodku ekranu, nie ma on nic wspólnego z obrotowym ruchem obrotowym! –

0

Oto kod, który napisałem jakiś czas temu dla 3-stopniowej przeglądarki uruchamiania rakiet. Mam większość informacji z http://www.euclideanspace.com/maths/geometry/rotations

Uwaga: odchyłu, skoku i obrotu może zmienić dla Ciebie w oparciu o jak skonfigurować system

 // Assuming the angles are in radians. 
      double p = curPitch * Math.PI/180.0/2.0; 
      double y = curYaw * Math.PI/180.0/2.0; 
      double r = curRoll * Math.PI/180.0/2.0; 

      double sinp = Math.sin(p); 
      double siny = Math.sin(y); 
      double sinr = Math.sin(r); 
      double cosp = Math.cos(p); 
      double cosy = Math.cos(y); 
      double cosr = Math.cos(r); 

      Vector3 axis = new Vector3(); 

      //here's the important part: how you get your quaternion vector! 
      axis.x = sinr * cosp * cosy - cosr * sinp * siny; 
      axis.y = cosr * sinp * cosy + sinr * cosp * siny; 
      axis.z = cosr * cosp * siny - sinr * sinp * cosy; 

      //now normalize the vector in case we want to use it again later 
      axis = Vector3.normalizeVector(axis); 

      orientation[1] = axis.x; 
      orientation[2] = axis.y; 
      orientation[3] = axis.z; 

      //w is omega: the angle to rotate about the quaternion 
      double w = cosr * cosp * cosy + sinr * sinp * siny; 

      w = Math.acos(w) * 2.0; 

      orientation[0] = w; 

      gl.glPushMatrix(); 

       //translate object first, then rotate it. 
       gl.glTranslated(curDisplacement[0] + saveDisplacement[0], -curDisplacement[1] + saveDisplacement[2], curDisplacement[2] + saveDisplacement[1]); 

       //this order might be messed up because I screwed up my coordinate system, but the idea is still there 
       gl.glRotated(orientation[0]*180/Math.PI, orientation[2]*180/Math.PI, orientation[3]*180/Math.PI, orientation[1]*180/Math.PI); 

      //place your objects 
      gl.glPopMatrix(); 

Nadzieja to pomaga koordynować!

Powiązane problemy