質問
速度ベクトルに沿って動く発射体があります。オブジェクトが常に速度ベクトルの方向を向いていることを確認する必要があります。さらに、行列ではなく四元数を使用してオブジェクトの回転を表現しています。
最初のステップは直交基底を見つけることであることを知っています:
forward = direction of velocity vector
up = vector.new(0, 1, 0)
right = cross(up, forward)
up = cross(forward, right)
基底を回転四元数に変換するにはどうすればよいですか
ソリューション
注:答えを提供してくれたNoel Hughesに謝意を表したいと思いますが、自分の経験を明確にしたいと思います。擬似コードは次のとおりです。
vec3 vel = direction of velocity vector
vec3 forward = (1, 0, 0) // Depends on direction your model faces. See below.
vec3 axis = cross(forward, vel)
if (axis == 0) then quit // Already facing the right direction!
axis = normalize(axis)
float theta = acos(vel.x/sqrt(vel.x^2, vel.y^2, vel.z^2))
quat result = (0, axis.y * sin(theta/2), axis.z * sin(theta/2), cos(theta/2)
四元数の最後の要素はスカラー部分で、最初の3つの要素は虚数部分です。また、上記の擬似コードでは、「モデル空間」内のオブジェクトが正のx軸を指します。私の場合、オブジェクトは実際には正のY軸を指しています。その場合、次の変更を行いました。
vec3 vel = direction of velocity vector
vec3 forward = (0, 1, 0) // Note that y-component is now 1
vec3 axis = cross(forward, vel)
if (axis == 0) then quit
axis = normalize(axis)
float theta = acos(vel.x/sqrt(vel.x^2, vel.y^2, vel.z^2))
quat result = (axis.x * sin(theta/2), 0, axis.z * sin(theta/2), cos(theta/2)
// Note that SECOND component above is now 0
解決
私は、縦軸を速度ベクトルに揃えること以外は、発射体の向きを気にかけず、縦軸は(1、0、0)のx軸であると仮定します。
あなたは正しい軌道に乗っています。速度ベクトル(vx、vy、vz)/ sqrt(vx ^ 2 + vy ^ 2 + vz ^ 2)を正規化し、x軸と交差して結果を正規化します-(0、yn、zn)-これは回転ですクォータニオンの軸。回転角度は、シータ= vx / sqrt(vx ^ 2 + vy ^ 2 + vz ^ 2)の逆余弦です。結果のクォータニオンは
(0、yn、zn)sn(theta / 2)cos(theta / 2)
質問がある場合は教えてください。
ノエル・ヒューズ nhughes1ster@gmail.com
他のヒント
vecmathライブラリ(Java)。それはずっと前からあり、私たちはコミュニティでそれを使用しています。 4タプルに基づいており、変換のための簡単な方法がなければ失望するでしょう。
また、期待される結果の単体テストを作成します。正と負、左利きと右利き、movinig / referenceフレームをごちゃ混ぜにするのはとても簡単です。単純なもの(例:xyz)から始めて、正しい答えがあることを確認してください。