我在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上正确显示?
For Reference这里是计算矩阵的函数:
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;
}
答案 0 :(得分:1)
为什么不在ogre中使用之前添加一个已经识别的额外旋转?
答案 1 :(得分:1)
我发现了问题。在我的函数中,单位向量在我将它们放在列中的交叉乘积之后计算,而我应该像往常一样将它们放入指定的matrix3单元格中的行中。虽然我指的是2d [] []中的元素,但关于行主和列主要的东西让我很困惑。
将矩阵计算函数的结果乘以该矩阵:
1 0 0
0 0 1
0 -1 0
然后用轴的另一个p / 2来调整整个结果解决了重映射问题,但我担心我的几何是倒置的。
答案 2 :(得分:0)
我对Matrix Rotation知之甚少,但是如果系统像您正在展示的那样旋转,我认为您应该执行以下操作:
X轴保持相同的方式,所以:
float Ax = accel[0];
float Ex = mag[0];
(Ogre3d)中的Y轴是([设备] [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);
试试