2009-12-09 28 views
6

arcball/trackballローテーションを実装しようとしていますが、 ローテーションの中心に問題があります。何となく、センターを私の画面の中心にしたい。OpenGLでクォータニオンを使って画面の中心をどのように回転させるのですか?

私がこれまで行ってきたことを説明しましょう。私はquaterion (:vector_start X vector_end、角度:回転軸vector_start * vector_end)作成した

私はglMultMatrixfでそれを使用するために、回転行列を作成したこと四元(マトリックス)から

をし、所望の回転を得る。

問題は、私のモデルがアークボールのように回転するように見えますが、それは常にローカル原点を中心に回転するはずです。どのように私はそれが画面の中心の周りに回転させることができます そのローカル起源がどこにあるかにかかわらず?

この問題の解決策は、回転軸全体を画面の中央で に変換してから回転を適用することができますが、これは可能でしょうか? ここに何かがありますか?

答えて

1

回転行列と平行移動行列を正しい順序で適用することで、これを解決できるはずです。 あなたのコードでは、元のT(-pos_x、-pos_y、-pos_z)に変換し、回転を適用し、再びT(pos_x、pos_y、pos_z)に変換することができます。これは、あなたの回転行列がどのように構築されるかに関係なく、一般的に機能します。

+0

はい、しかし、私はglMultMatrixf()を適用しても、OpenGLはモデルをローカル原点の周りで回転させませんか? 私は原点に回転すると(glRotatef()ではなくglMultMatrix()を使用して)回転して再び元に戻すと、元のモデルが原点を中心に再回転します。 –

+0

glTranslatef()で翻訳してから、あなたの回転行列glMultMatrix()を掛けて、glTranslatef()を使って再び翻訳し直してください。これは単にglMultMatrix()を呼び出すのとは対照的です。それはうまくいかない? – catchmeifyoutry

+0

いいえ動作しません。それは、glMultMatrixfによって適用された回転行列から言われるようにモデルを回転させるが、そのローカル起源の周りを回転させるということである。私は回転クォータニオンを オイラー角に変換しようとしましたが、glRotatef(Yaw、0.、0.、1.)を適用しました。 glRotatef(Pich、0.、1.、0); glRotatef(ロール、1.、0.、0。); glMultMatrixf()を直接適用するのではなく、回転が画面中央付近にある間に、円弧とは何の関係もありません 回転! –

0

ここに私が3段階ロケット打ち上げのために書いたコードがあります。私は注意

http://www.euclideanspace.com/maths/geometry/rotationsからの情報のほとんどを得た:ヨー、ピッチ、ロールは、あなたのシステム

 // 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(); 

これが役に立てば幸い座標の設定方法に基づいて、あなたのために変更されることがあり!

関連する問題