3

ローカル座標系を定義するために使用する剛体上の 3 点 (3D、xyz) を追跡しています。このローカル座標系の方向 (参照のグローバル フレーム内) を使用して、VR プログラムでビューの方向を設定しています。これを行い、オイラー角によるジンバルロックを回避するために、四元数を使用してビューの向きを設定しようとしています。

3 点から回転行列を作成し、ウィキペディアに記載されているこの方法を使用して、想定される同等の四元数を抽出します。次に、ビューの向きを計算された四元数に設定するだけです。

ただし、ヨーとロールの変化も同時に確認できるはずなのに、主に 1 つの自由度 (ピッチ) しかないことがわかります。回転行列からオイラー角を抽出しましたが、ジンバルロック以外ではうまく機能します。したがって、私の場合は不適切ですが、回転行列が使用できると確信しています。

私の質問は、想定される同等の四元数が「ピッチ」の自由度のみを変更するように見えるのはなぜですか?

クォータニオンが 1 軸を中心とした回転であることは承知していますが、回転行列から派生した場合、最終結果はオイラー角を設定した場合と同じになると思いましたか?

Pythonでの私のコードは次のとおりです。

import viz
import numpy as np

vec1 = np.array([-0.96803,-0.25022,0.01751],dtype=float)
vec3 = np.array([-0.024815,0.96553,0.07863],dtype=float)
vec4 = np.array([-0.03655,0.07178,-0.99675],dtype=float)
#normalize to unit length
vec1 = vec1 / np.linalg.norm(vec1)
vec3 = vec3 / np.linalg.norm(vec3)
vec4 = vec4 / np.linalg.norm(vec4)

M1 = np.zeros((3,3),dtype=float) #rotation matrix

#rotation matrix setup
M1[:,0] = vec1
M1[:,1] = vec3
M1[:,2] = vec4

#get the real part of the quaternion first
r = np.math.sqrt(float(1)+M1[0,0]+M1[1,1]+M1[2,2])*0.5
i = (M1[2,1]-M1[1,2])/(4*r)
j = (M1[0,2]-M1[2,0])/(4*r)
k = (M1[1,0]-M1[0,1])/(4*r)

viz.MainView.setQuat(i,j,k,r)

どんな助けやアイデアも素晴らしいでしょう!

4

1 に答える 1

3

ここでの重要な問題は、適切な 3x3 回転行列のみに関連するアルゴリズムを、直交しておらず、不適切な回転行列に非常に近い行列に適用したことです。問題の主な原因は後者です。

あなたの行列M1は

array([[-0.9994477 , -0.02887993,  0.0164005 ],
       [-0.02958325,  0.99862763, -0.04323132],
       [ 0.01513678,  0.0436899 ,  0.99893047]])

適切な回転行列からこの不適切な行列に四元数を抽出するアルゴリズムを不適切に適用すると、ナンセンスになります。特に、M[2,1]は にほぼ等しい -M[1,2]M[0,2]は にほぼ等しい M[2,0]、は にほぼM[1,0]等しい ためM[0,1]、ほとんど純粋なロールのように見えるものが得られます。

注: 行列からオイラー角を抽出するアルゴリズムにも同じことが当てはまります。これらのアルゴリズムはすべて、行列が適切な回転行列であると想定しています。それらを不適切な回転行列に不適切に適用すると、ナンセンスになります。

于 2015-08-25T18:59:02.510 に答える