0

私は、ネットワークを介して電話のセンサーデータを読み取り、デバイスのマトリックスを計算するc++プログラムでAndroidのgetRotationMatrixの適応バージョンを使用しています。

この関数は正常に機能し、デバイスの向きを計算します。残念ながら、Ogre3dの軸システムはデバイスとは異なります。したがって、x軸を中心とした回転は正常に機能しますが、y軸とz軸は間違っています。デバイスレベルを保持し、北を指します(単位行列)。私が投げるとき、回転は正しいです。しかし、私が転がったり横揺れたりすると、回転が交互になります。Ogre3dではロールはヨーであり、その逆も同様です。

    (Ogre3d)                         ([Device][5])

   ^ +y-axis                       ^ +z-axis                                  
   *                               *                                 
   *                               *                                 
   *                               *    ^ +y-axis                             
   *                               *   *                               
   *                               *  *                                
   *                               * *                                 
   ************> + x-axis          ************> +x-axis                      
  *                                                                   
 *                                                                    
v +z-axis                                                                     

2軸システムをざっと見ると、Ogreのシステム(左側)は、基本的に、デバイスのシステムがx軸を中心に反時計回りに90度回転しているように見えます。

マトリックスを計算する前にセンサー値を最初に割り当てるときに、さまざまな組み合わせを試してみましたが、組み合わせが正しく機能していないようです。回転行列getRotationMatrix()がOgre3Dで正しく表示されることを確認するにはどうすればよいですか?

参考までに、行列を計算する関数は次のとおりです。

bool getRotationMatrix() {
    //sensor data coming through the network are 
    //stored in accel(accelerometer) and mag(geomagnetic)
    //vars which the function has access to
    float Ax = accel[0]; float Ay = accel[1];   float Az = accel[2];
    float Ex = mag[0];   float Ey = mag[1];     float Ez = mag[2];

    float Hx = Ey * Az - Ez * Ay;
    float Hy = Ez * Ax - Ex * Az;
    float Hz = Ex * Ay - Ey * Ax;
    float normH = (float) Math::Sqrt(Hx * Hx + Hy * Hy + Hz * Hz);
    if (normH < 0.1f) {
        // device is close to free fall (or in space?), or close to
        // magnetic north pole. Typical values are  > 100.
        return false;
    }
    float invH = 1.0f / normH;
    Hx *= invH;
    Hy *= invH;
    Hz *= invH;
    float invA = 1.0f / (float) Math::Sqrt(Ax * Ax + Ay * Ay + Az * Az);
    Ax *= invA;
    Ay *= invA;
    Az *= invA;
    float Mx = Ay * Hz - Az * Hy;
    float My = Az * Hx - Ax * Hz;
    float Mz = Ax * Hy - Ay * Hx;

    //ogre3d's matrix3 is column-major whereas getrotatinomatrix produces
    //a row-major matrix thus i have tranposed it here
    orientation[0][0] = Hx; orientation[0][2] = Mx; orientation[0][2] = Ax;
    orientation[1][0] = Hy; orientation[1][3] = My; orientation[1][2] = Ay;
    orientation[2][0] = Hz; orientation[2][4] = Mz; orientation[2][2] = Az;

    return true;
}
4

3 に答える 3

1

鬼で使用する前に、すでに特定した1つのローテーションを追加してみませんか?

于 2011-05-02T02:44:41.463 に答える
1

問題を見つけました。私の関数では、外積の後に計算された単位ベクトルを列に配置しますが、通常どおり、指定されたmatrix3セルの行に配置する必要があります。2d [] []の要素を参照していても、行メジャーと列メジャーに関する何かが私を混乱させました。

行列計算関数の結果にこの行列を掛けます。

1 0 0

0 0 1

0 -1 0

次に、結果全体を軸を中心に別のp / 2でピッチングすると、リマッ​​プの問題は解決しましたが、ジオメトリが反転するのではないかと心配しています。

于 2011-05-04T07:23:13.573 に答える
0

マトリックスの回転についてはよくわかりませんが、システムが表示されているように回転する場合は、次のことを行う必要があると思います。

X軸は同じままなので、次のようになります。

float Ax = accel[0];
float Ex = mag[0];

(Ogre3d)のY軸は([Device] [5])のZ軸なので、次のようになります。

float Ay = accel[2];
float Ey = mag[2];

(Ogre3d)のZ軸は、([Device] [5])のY軸の反対であるため、次のようになります。

float Az = accel[1] * (-1);
float Ez = mag[1] * (-1);

それを試してみてください

于 2011-05-01T12:09:50.727 に答える