web-dev-qa-db-ja.com

クォータニオン回転を回転行列に変換しますか?

基本的に、クォータリオン(qx、qy、qz、qw)が与えられた場合...それをOpenGL回転行列に変換するにはどうすればよいですか?また、どの行列行が「上」、「右」、「順」などであるかにも興味があります...ベクトルで必要なクォータニオンでのカメラの回転があります...

17
Polaris878

次のコードはクォータニオン(qw、qx、qy、qz)に基づいており、順序はブーストクォータニオンに基づいています。

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

まず、クォータニオンを正規化する必要があります。

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

次に、マトリックスを作成できます。

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

行列クラスによっては、OpenGLに渡す前に転置する必要がある場合があります。

32
Malte Clasen

これを行う1つの方法は、視覚化が非常に簡単で、クォータニオンによって指定された回転を基底ベクトル(1,0,0)、(0,1,0)、および(0,0,1)に適用することです。 。回転された値は、元のシステムに対して回転されたシステムの基底ベクトルを示します。これらのベクトルを使用して、回転行列の行を形成します。結果の行列とその転置は、元のシステムと回転したシステムの間の順方向および逆方向の変換を表します。

私はOpenGLで使用される規則に精通していないので、誰か他の人があなたの質問のその部分に答えることができるかもしれません...

9
Jim Lewis

回転行列をまったく扱う必要がないかもしれません。行列に変換してベクトルを乗算するよりも高速に見える方法は次のとおりです。

  // 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=3a84e00a70ccb046cfc87ac39881a3d

2
defhlt

glmを使用すると、キャスト演算子を使用できます。したがって、matrix4からquaternionに変換するには、次のように記述します。

glm :: mat4_cast(quaternion_name)

0
Raino sommer