Android SensorManager strange how to remapCoordinateSystem

前端 未结 5 1787
感情败类
感情败类 2020-12-12 16:57

API Demos -> Graphics -> Compass

It works properly only, until you don\'t change the device natural orientation. In most phones is the portrait and most 10 inch tabl

5条回答
  •  旧时难觅i
    2020-12-12 17:26

    If the phone UI locked to the rotation 0, I am getting the following values without remapCoordinateSystem()

    Pitch (phone) = -Pitch   (API)
    Roll  (phone) =  Roll     (API)
    Yaw   (phone) =  Azimuth  (API)
    
    • at least near 0,0,0 values.

    If the phone UI forced to rotation 90:

    Yaw value has -90 degree ( - PI/2 ) at old orientation!!! => I will go to East in reality instead of North.

    If I take phone to 0,0,0 position:

    Pitch (phone) = -Roll    (API)
    Roll  (phone) = -Pitch   (API)
    Yaw   (phone) =  Azimuth (API)
    

    If the phone UI forced to rotation 180:

    Yaw value has +/-180 degree ( +/- PI ) at old orientation!!! => I will go to South in reality instead of North.

    If I take phone to 0,0,0 position:

    Pitch (phone) =  Pitch   (API)
    Roll  (phone) = -Roll    (API)
    Yaw   (phone) =  Azimuth (API)
    

    If the phone UI forced to rotation 270:

    Yaw value has +90 degree ( + PI/2 ) at old orientation!!! => I will go to West in reality instead of North.

    If I take phone to 0,0,0 position:

    Pitch (phone) =  Roll    (API)
    Roll  (phone) =  Pitch   (API)
    Yaw   (phone) =  Azimuth (API)
    

    I wrote a little fix, and tested with: android:screenOrientation="fullSensor"

    public static final void fixRotation0(float[] orientation) { //azimuth, pitch, roll
        orientation[1] = -orientation[1]; // pitch = -pitch
    }
    
    public static final void fixRotation90(float[] orientation) { //azimuth, pitch, roll
        orientation[0] += Math.PI / 2f; // offset
        float tmpOldPitch = orientation[1];
        orientation[1] = -orientation[2]; //pitch = -roll
        orientation[2] = -tmpOldPitch; // roll  = -pitch    
    }
    
    public static final void fixRotation180(float[] orientation) { //azimuth, pitch, roll
        orientation[0] = (float)(orientation[0] > 0f ? (orientation[0] - Math.PI) : (orientation[0] + Math.PI)); // offset
        orientation[2] = -orientation[2]; // roll = -roll
    }
    
    public static final void fixRotation270(float[] orientation) { //azimuth, pitch, roll
        orientation[0] -= Math.PI / 2; // offset
        float tmpOldPitch = orientation[1];
        orientation[1] = orientation[2]; //pitch = roll
        orientation[2] = tmpOldPitch; // roll  = pitch  
    }
    

    In most cases is working. When you rotate quickly 180 degree around 1 axis, than the system will be screwed!

    The full code available at Github

提交回复
热议问题