Orientation from Android Accelerometer

时光毁灭记忆、已成空白 提交于 2019-11-28 12:00:55

In fact, the accelerometer axises are relative to the default orientation of the device.

Here how to deal with it:

static void canonicalOrientationToScreenOrientation(
         int displayRotation, float[] canVec, float[] screenVec) 
{ 
    final int axisSwap[][] = { 
    {  1,  -1,  0,  1  },     // ROTATION_0 
    {-1,  -1,  1,  0  },     // ROTATION_90 
    {-1,    1,  0,  1  },     // ROTATION_180 
    {  1,    1,  1,  0  }  }; // ROTATION_270 

    final int[] as = axisSwap[displayRotation]; 
    screenVec[0]  =  (float)as[0] * canVec[ as[2] ]; 
    screenVec[1]  =  (float)as[1] * canVec[ as[3] ]; 
    screenVec[2]  =  canVec[2]; 
} 

This solution was provided by NVidia. Check their white paper about Android Accelerometer for more details.

just wanted to add something to Hartok's answer as I couldn't understand it at first...

I've rewritten the method to be:

public static float[] adjustAccelOrientation(int displayRotation, float[] eventValues) 
{ 
    float[] adjustedValues = new float[3];

    final int axisSwap[][] = {
    {  1,  -1,  0,  1  },     // ROTATION_0 
    {-1,  -1,  1,  0  },     // ROTATION_90 
    {-1,    1,  0,  1  },     // ROTATION_180 
    {  1,    1,  1,  0  }  }; // ROTATION_270 

    final int[] as = axisSwap[displayRotation]; 
    adjustedValues[0]  =  (float)as[0] * eventValues[ as[2] ]; 
    adjustedValues[1]  =  (float)as[1] * eventValues[ as[3] ]; 
    adjustedValues[2]  =  eventValues[2];

    return adjustedValues;
}

Exactly the same thing, just with more user friendly variable names and I recreate the float internally because I needed it like that... Simply call this function, put in the getRotation and the event.values float array, check the values of its return float array and pick whatever number you prefer...

Hope this helps someone!

As far as I know this is because of default orientation of device. F.e. new android tablets with Honeycomb have portrait orientation when held like in landscape on phones.

http://developer.android.com/reference/android/hardware/SensorEvent.html

In android documentation there is information that:

The coordinate-system is defined relative to the screen of the phone in its default orientation. The axes are not swapped when the device's screen orientation changes.

The X axis is horizontal and points to the right, the Y axis is vertical and points up and the Z axis points towards the outside of the front face of the screen. In this system, coordinates behind the screen have negative Z values.

Maybe one of this devices has also landscape as a portrait (default) orientation?

Hope it helps you somehow.

As stated before, the default screen orientation can vary from device to device. The accelerometer coordinates will always match the devices default orientation. This behavior is different for screen coordinates. As the device rotates the screen coordinates rotates as well, such that (0, 0) is always the current top left corner of the screen. On a device with a default orientation of portrait, locking the orientation to portrait will ensure that the sensor coordinates run along the same axis as the screen coordinates regardless of the rotation. On the other hand, locking the screen orientation to portrait on a device with a default landscape orientation will cause the sensor axis to run in a different direction than the screen axis.

This article: http://android-developers.blogspot.com/2010/09/one-screen-turn-deserves-another.html explains this in greater depth as well as gives a solution for dealing with the problem.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!