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                                                                     

快速浏览一下两轴系统,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

我发现了问题。在我的函数中,在叉积之后计算的单位向量我将它们放在列中,而我应该像往常一样将它们放在指定的 matrix3 单元格中的行中。尽管我指的是 2d [][] 中的元素,但关于行优先和列优先的一些事情让我感到困惑。

将矩阵计算函数的结果与该矩阵相乘:

1 0 0

0 0 1

0 -1 0

然后将整个结果通过另一个 p/2 关于轴来解决重映射问题,但我担心我的几何形状是倒置的。

于 2011-05-04T07:23:13.573 回答
1

为什么不在你在食人魔中使用它之前添加一个你已经确定的额外旋转呢?

于 2011-05-02T02:44:41.463 回答
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 回答