在iPhone中为Opengl Es获取定位设备

时间:2011-05-10 13:56:06

标签: iphone opengl-es rotation accelerometer magnetometer

我正在尝试转换地磁和加速度计以在opengl ES1中旋转相机,我发现了一些来自android的代码并为iPhone改变了这个代码,实际上它或多或少都有效,但是有一些错误,我我无法找到这个错误,我把代码,也是对Opengl Es1的调用:glLoadMatrixf((GLfloat*)matrix);

- (void) GetAccelerometerMatrix:(GLfloat *) matrix headingX: (float)hx headingY:(float)hy headingZ:(float)hz;
{

    _geomagnetic[0] = hx * (FILTERINGFACTOR-0.05) + _geomagnetic[0] * (1.0 - FILTERINGFACTOR-0.5)+ _geomagnetic[3] * (0.55);
    _geomagnetic[1] = hy * (FILTERINGFACTOR-0.05) + _geomagnetic[1] * (1.0 - FILTERINGFACTOR-0.5)+ _geomagnetic[4] *  (0.55);
    _geomagnetic[2] = hz * (FILTERINGFACTOR-0.05) + _geomagnetic[2] * (1.0 - FILTERINGFACTOR-0.5)+ _geomagnetic[5] *  (0.55);

    _geomagnetic[3]=_geomagnetic[0] ;
    _geomagnetic[4]=_geomagnetic[1];
    _geomagnetic[5]=_geomagnetic[2];


        //Clear matrix to be used to rotate from the current referential to one based on the gravity vector
    bzero(matrix, sizeof(matrix));



    //MAGNETIC
    float Ex = -_geomagnetic[1];    
    float Ey =_geomagnetic[0];
    float Ez =_geomagnetic[2];

    //ACCELEROMETER
    float Ax=  -_accelerometer[0];
    float Ay=  _accelerometer[1] ;
    float Az=  _accelerometer[2] ;


    float Hx = Ey*Az - Ez*Ay;
    float Hy= Ez*Ax - Ex*Az;
    float Hz = Ex*Ay - Ey*Ax;

    float normH = (float)sqrt(Hx*Hx + Hy*Hy + Hz*Hz);


    float invH = 1.0f / normH;
    Hx *= invH;
    Hy *= invH;
    Hz *= invH;

    float invA = 1.0f / (float)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;

    // if (mOut.f != null) {

    matrix[0]  = Hx;    matrix[1]  = Hy;    matrix[2]  = Hz;   matrix[3]  = 0;
    matrix[4]  = Mx;    matrix[5]  = My;    matrix[6]  = Mz;   matrix[7]  = 0;
    matrix[8]  = Ax;    matrix[9]  = Ay;    matrix[10] = Az;   matrix[11] = 0;
    matrix[12] = 0;     matrix[13] = 0;     matrix[14] = 0;    matrix[15] = 1;


}

非常感谢您的帮助。

编辑:iPhone在横向上是永久性的,我知道出现问题,因为在Opengl Es中绘制的对象会出现两次。

2 个答案:

答案 0 :(得分:2)

您是否看过Apple的GLGravity示例代码?它通过操纵模型视图矩阵来响应加速度计输入的变化,从而完成与此处非常相似的操作。

答案 1 :(得分:1)

我无法发现发布的代码有任何问题,并表示问题出在其他地方。如果有帮助,我对发布的代码的分析就是:

处理_geomagnetic 0-5的前六行产生一个非常简单的低频滤波器,假设您定期调用该方法。因此,您最终得到了一个磁力计矢量版本,希望能够消除高频抖动。

bzero将结果归零,准备积累。

声明和分配给Hz的线路采用磁力计和加速度计矢量并执行交叉乘积。因此,H(x,y,z)现在是与加速度计(假设为“向下”)和磁力计(将向前+向上)成直角的向量。称之为侧向量。

invH和invA的东西,直到invA乘以Az,确保侧面和加速度计/向下矢量具有单位长度。

然后创建M(x,y,z),作为侧向向量和向下向量的叉积(即,与这两个向量成直角的向量)。所以它给出了前向量。

最后,这三个向量用于填充矩阵,利用了正交3x3矩阵的逆是其转置的事实(虽然这有点被事物布局隐藏 - 注意数组指数)。你实际上直接在矩阵中设置了所有内容,因此在纯粹的结果术语中不需要bzero。

glLoadMatrixf是正确的用法,因为这是你在OpenGL ES 1.x中乘以任意列主矩阵的方式。