18

API デモ -> グラフィック ->コンパス

デバイスの自然な向きを変更しない限り、正しく機能します。ほとんどの携帯電話は縦向きで、ほとんどの 10 インチ タブレットは横向きです。変更する場合は、これを 90 度回転させる必要があります。そのシステムの 3D 修正を希望します。

100% remapCoordinateSystem()メソッドを使用する必要があります。

どのように(コード)それらの軸マッピング(理論的な数学)がどのように計算されるかの説明を見ることができれば、それはいいでしょう。

理解しようとしましたが、線形代数をすべて忘れていました。

ここでは、なぜ使用する必要があるかを示していますが、使用方法は示していません!

float R[] = new float[9];
// X  (product of Y and Z) and roughly points East
// Y: points to Magnetic NORTH and tangential to ground
// Z: points to SKY and perpendicular to ground
float I[] = new float[9];
boolean success = SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic);

それらの座標はこの位置にあるようです:

デバイスの向き

場合にのみ

getWindowManager().getDefaultDisplay().getRotation() == Surface.ROTATION_0

問題は、このコードを完成させる方法です: - これらのケース ブランチ

switch (mScreenRotation) {
    case Surface.ROTATION_0:
    Log.v("SurfaceRemap", "0 degree");
    axisX = SensorManager.AXIS_X;// is this valid?
    axisY = SensorManager.AXIS_Y;// is this valid?
    break;

    case Surface.ROTATION_90:
    Log.v("SurfaceRemap", "90 degree");
    // examples says remapCoordinateSystem(inR, AXIS_Y, AXIS_MINUS_X, outR);
    axisX = SensorManager.AXIS_Y;
    axisY = SensorManager.AXIS_MINUS_X;
    break;

    case Surface.ROTATION_180:
    Log.v("SurfaceRemap", "180 degree");
    break;

    case Surface.ROTATION_270:
    Log.v("SurfaceRemap", "270 degree");
    break;

    default:
    Log.v("SurfaceRemap", "don't know the mScreenRotation value: "+mScreenRotation+" you should never seen this message!");
    break;
}


boolean remapped = SensorManager.remapCoordinateSystem(R, axisX, axisY, R);

float orientation[] = new float[3];

SensorManager.getOrientation(R, orientation);// All three angles above are in radians and positive in the counter-clockwise direction.
inclination = SensorManager.getInclination(I);

編集:私は小さなテストアプリケーションを書きました。画面上に画面の回転を表示します:0、90、270度(現在180度にすることはできません)

Rotation 0 が変更されていない場合 ( axisX = SensorManager.AXIS_X;axisY = SensorManager.AXIS_Y;)、90 度は次のようになります。

axisX = SensorManager.AXIS_MINUS_Y;
axisY = SensorManager.AXIS_X;

Google のドキュメントに間違った値が記載されているよりも! 問題はどこだ!?

getRotationMatrixはこれを返します:

ここに画像の説明を入力

X はベクトル積 YZ として定義されます (デバイスの現在の位置で地面に接し、おおよそ東を指します)。

Y は、デバイスの現在の位置で地面に接しており、磁北極を指しています。

Z は空を指し、地面に対して垂直です。

上の電話を見てください!バックカメラを地面に向けて、左から右に行きたいです。

getOrientationはこれを返します:

ここに画像の説明を入力

X はベクトル積 YZ として定義されます (デバイスの現在の位置で地面に接し、おおよそ西を指します)。

Y は、デバイスの現在の位置で地面に接しており、磁北極を指しています。

Z は地球の中心を指し、地面に対して垂直です。

values[0]: 方位角、Z 軸を中心とした回転。

values[1]: ピッチ、X 軸周りの回転。

values[2]: ロール、Y 軸を中心とした回転。

電話はどうあるべきですか?

最後に、航空機のような角度の値が欲しいです。北に向かっている私の電話 (私): (ヨーは方位角です)

ここに画像の説明を入力

              if ScreenRotation = 0 degree
Pitch axis = -orientationAxisX  =  rotationAxisX
Roll axis  =  orientationAxisY  =  rotationAxisY 
Yaw axis   =  orientationAxisZ  = -rotationAxisZ
4

5 に答える 5

27

スイッチ ブランチを完了するには、remapCoordinateSystem メソッドの javadoc に従って考えてみます。

X は、デバイスの X 軸がマッピングされるワールド軸と方向を定義します。
Y は、デバイスの Y 軸がマップされるワールド軸と方向を定義します。

デバイスを自然な向き (90 度、180 度、または 270 度) から回転させて、次のことを自問してください。元のデバイスの向きの X 正の軸は、現在のデバイスの向きに対応する軸に対応していますか? Y 軸についても同様です。

したがって、デバイスが 90 度回転している場合、元の X 軸の正の軸が現在の正の Y 軸に対応し、元の正の Y 軸が現在の向きの負の X 軸に対応することがわかります。

したがって、次のようになります。

switch (mScreenRotation) {
    case Surface.ROTATION_0:
        axisX = SensorManager.AXIS_X;
    axisY = SensorManager.AXIS_Y;
        break;

    case Surface.ROTATION_90:
        axisX = SensorManager.AXIS_Y;
    axisY = SensorManager.AXIS_MINUS_X;
        break;

    case Surface.ROTATION_180:
        axisX = SensorManager.AXIS_MINUS_X;
    axisY = SensorManager.AXIS_MINUS_Y;
        break;

    case Surface.ROTATION_270:
        axisX = SensorManager.AXIS_MINUS_Y;
    axisY = SensorManager.AXIS_X;
        break;

    default:
        break;
}

それは私のために働いた、それが役立つことを願っています。

于 2013-12-24T11:12:07.697 に答える
3

これは、アプリケーションで魔法を行う方法です。

        float[] rotationMatrixOrig = new float[9];
        SensorManager.getRotationMatrix(rotationMatrixOrig, null, lastAccelerometerValue, lastMagnetometerValue);

        int screenRotation = app.getCurrentActivity().getWindowManager().getDefaultDisplay().getRotation();
        int axisX, axisY;
        boolean isUpSideDown = lastAccelerometerValue[2] < 0;

        switch (screenRotation) {
            case Surface.ROTATION_0:
                axisX = (isUpSideDown ? SensorManager.AXIS_MINUS_X : SensorManager.AXIS_X);
                axisY = (Math.abs(lastAccelerometerValue[1]) > 6.0f ? 
                        (isUpSideDown ? SensorManager.AXIS_MINUS_Z : SensorManager.AXIS_Z) :
                        (isUpSideDown ? SensorManager.AXIS_MINUS_Y : SensorManager.AXIS_Y));
                break;
            case Surface.ROTATION_90:
                axisX = (isUpSideDown ? SensorManager.AXIS_MINUS_Y : SensorManager.AXIS_Y);
                axisY = (Math.abs(lastAccelerometerValue[0]) > 6.0f ? 
                        (isUpSideDown ? SensorManager.AXIS_Z : SensorManager.AXIS_MINUS_Z) :
                        (isUpSideDown ? SensorManager.AXIS_X : SensorManager.AXIS_MINUS_X));
                break;
            case  Surface.ROTATION_180:
                axisX = (isUpSideDown ? SensorManager.AXIS_X : SensorManager.AXIS_MINUS_X);
                axisY = (Math.abs(lastAccelerometerValue[1]) > 6.0f ? 
                        (isUpSideDown ? SensorManager.AXIS_Z : SensorManager.AXIS_MINUS_Z) :
                        (isUpSideDown ? SensorManager.AXIS_Y : SensorManager.AXIS_MINUS_Y));
                break;
            case Surface.ROTATION_270:
                axisX = (isUpSideDown ? SensorManager.AXIS_Y : SensorManager.AXIS_MINUS_Y);
                axisY = (Math.abs(lastAccelerometerValue[0]) > 6.0f ? 
                        (isUpSideDown ? SensorManager.AXIS_MINUS_Z : SensorManager.AXIS_Z) :
                        (isUpSideDown ? SensorManager.AXIS_MINUS_X : SensorManager.AXIS_X));
                break;
            default:
                axisX = (isUpSideDown ? SensorManager.AXIS_MINUS_X : SensorManager.AXIS_X);
                axisY = (isUpSideDown ? SensorManager.AXIS_MINUS_Y : SensorManager.AXIS_Y);
        }

        float[] rotationMatrix = new float[9];
        SensorManager.remapCoordinateSystem(rotationMatrixOrig, axisX, axisY, rotationMatrix);
于 2015-02-06T03:48:20.337 に答える