Android,基于地磁传感器调用glRotatef

时间:2014-04-04 20:15:16

标签: java android opengl-es 3d

我有一个渲染多维数据集的应用。我对使用openGL进行3D操作有点新意,但基本上我想要的是我的立方体的一角始终指向北方,但也根据地磁传感器定位自己。

这样,当用户将手机与地面平行并朝北时,角落将指向屏幕上的“向上”,而如果用户将手机竖直,则角落将指向“离开”用户,朝着手机的背面。

我在2d只在一个旋转轴上写这个没有问题,这样如果手机与地面平行,它就会指向角落的北角。

然而,当我制作这个3D时,其中两个轴似乎工作正常,但我第一次使用的轴似乎没有表现出相同的效果。

我使用以下代码获取每个代码的轮换:

    gl.glPushMatrix();
    gl.glTranslatef(0,0,-4); 
    //get target angle
    targetAngle1 = rotationHandler.getRotation1();
    targetAngle2 = rotationHandler.getRotation2();
    targetAngle3 = rotationHandler.

    if (Math.abs(getShortestAngle(targetAngle1, currentAngle)) > 5) //this is to create a 5 degree "dead zone" so the compass isnt shaky
        currentAngle1 = (getShortestAngle(currentAngle, targetAngle1) > 0) ?
        currentAngle+1f : currentAngle-1f; //increase or decrease the current angle to move it towards the target angle

    if (Math.abs(getShortestAngle(targetAngle2, currentAngle2))>5)
        currentAngle2 = (getShortestAngle(currentAngle2, targetAngle2) > 0) ? 
        currentAngle2 + 1f : currentAngle2-1f;

    if (Math.abs(getShortestAngle(targetAngle3, currentAngle3))>5)
        currentAngle3 = (getShortestAngle(currentAngle3, targetAngle3) > 0) ? 
        currentAngle3 + 1f : currentAngle3 - 1f;


    gl.glRotatef(currentAngle, 0, 0, -4);
    gl.glRotatef(currentAngle2, 0, -4, 0); 
    gl.glRotatef(currentAngle3, -4, 0, 0); 
    cube.draw(gl);
    gl.glPopMatrix();

使用currentAngle2和currentAngle3的glRotatef调用似乎在相对于立方体的轴上旋转立方体,而第一次调用似乎在相对于屏幕的轴上旋转它。当我注释掉任何两个旋转调用时,第三个按预期工作。但我似乎无法弄清楚如何让他们一起工作。

--- --- EDIT

我发现即使拿走第一个电话,我也可以将立方体旋转到几乎任何可能的位置。因此,似乎我将不得不想出一个算法来计算适当的旋转。老实说,我不知道我是否能做到,但如果我弄明白的话,我会在这里发布。

1 个答案:

答案 0 :(得分:0)

这可能不是最好的解决方案,但只要手机不完全平整,它似乎就能正常工作。

将模型更改为矩形棱镜后,我可以更清楚地解决问题。我只使用前两个轴,甚至没有触及最后一个轴。我把棱镜看作是一架战斗机 - 为了向左或向右转动,我将它旋转到一边,然后向上或向下改变音高。然后我"不旋转"它,并再次改变音高,以便适当地指出它。

    public void findTargetRotation(float rotationAngle, float pitchAngle, GL10 gl){
    //first, enable rotation around a vertical axis by rotating on frontBack axis by -90 degrees
    gl.glRotatef(-90, 0, -4, 0);
    //rotate around the leftRight axis by the angle1 amount
    gl.glRotatef(rotationAngle, 0,-4,0);

    //then rotate on frontBack axis by 90 degrees again, to straighten out
    gl.glRotatef(90, 0, -4, 0);
    //lastly, rotate around the leftRight axis to point it up or down
    gl.glRotatef(pitchAngle, -4, 0, 0);
}

只要pitchAngle不是非常接近或等于0,这似乎就可以工作。所以我只是添加了一些代码来处理它,如果pitchAngle非常小的话就像2D对象一样。

这可能是一个更好的解决方案,但至少可行。