【问题标题】:Remap rotation matrix to different axis system将旋转矩阵重新映射到不同的轴系
【发布时间】:2011-05-01 03:27:08
【问题描述】:

我在一个 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;
}

【问题讨论】:

  • 只是想知道,像这样使用来自 Android 的代码移植代码是否合法?我希望我能理解数学背后的含义(我认为这不是 IP),这样我就可以自己写了。
  • 当然是合法的。 acc = 来自加速度计的数据 ma = 来自磁传感器的数据。这是 Ogre3D 函数,它认为它非常简单: Vector3 H = ma.crossProduct(acc);浮动 normH = (float) H.length();浮动 invH = 1.0f / normH; H *= invH;浮动 invA = 1.0f / (float) acc.length(); ac *= invA; Vector3 M = acc.crossProduct(H);方向[0][0] = H.x;方向[0][1] = H.y;方向[0][2] = H.z;方向[1][0] = M.x;方向[1][1] = M.y;方向[1][2] = M.z;方向[2][0] = acc.x;方向[2][1] = acc.y;方向[2][2] = acc.z;
  • 是的,但我们只是从 Android 获取 Java 代码并转换为 C++。那合法吗?我们不应该从头开始编写代码还是完全由我们自己来编写代码?
  • 但该方法是一种非常著名的方法,它基于 1968 年的两个已知向量确定方向。Google 不拥有该方法的任何专利或权利。 en.wikipedia.org/wiki/Triad_Method
  • 问题不在于方法。事实上,代码来自 Google 拥有的代码。

标签: android matrix ogre3d remap


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

    1 0 0

    0 0 1

    0 -1 0

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

    【讨论】:

      【解决方案3】:

      我对矩阵旋转知之甚少,但如果系统像您展示的那样旋转,我认为您应该执行以下操作:

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

      试试看

      【讨论】:

      • 我已经试过了。我又试了一次,不幸的是它不起作用:/它确实用z切换了y,但是z轴上的旋转是相反的,无论我尝试什么组合,我都无法做到正确(现在已经尝试了几天) .不过还是谢谢!感谢您的帮助。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-13
      • 2013-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多