Android陀螺仪倾斜

时间:2018-03-29 05:41:52

标签: android gyroscope pitch

先谢谢你的帮助。

我找到了很多使用陀螺仪的例子。但我找不到适合我的。  我想制作一个简单的问答游戏,当我将VM向前和向后倾斜90度时进行操作。许多例子说我可能会使用陀螺仪的“音高”值。你能给我一些建议吗?

1 个答案:

答案 0 :(得分:0)

我做了类似的事情,我需要绘制一个包含附近地方的矩形,并且必须将它指向该地点并显示细节。

public void onSensorChanged(SensorEvent event) {
        final Handler handler = new Handler();
        switch (event.sensor.getType()) {
 case Sensor.TYPE_ACCELEROMETER:
                mAcceleromterReading =
                        SensorUtilities.filterSensors(event.values, mAcceleromterReading);
break;

            case Sensor.TYPE_MAGNETIC_FIELD:
                mMagnetometerReading =
                        SensorUtilities.filterSensors(event.values, mMagnetometerReading);
                break;

 float[] orientation =
                    SensorUtilities.computeDeviceOrientation(mAcceleromterReading, mMagnetometerReading);
if (orientation != null) {
 float azimuth = (float) Math.toDegrees(orientation[0]);
                if (azimuth < 0) {
                    azimuth += 360f;
                }

                // Convert pitch and roll from radians to degrees
                float pitch = (float) Math.toDegrees(orientation[1]);
                float roll = (float) Math.toDegrees(orientation[2]);
if (abs(pitch - pitchPrev) > PITCH_THRESHOLD && abs(roll - rollPrev) > ROLL_THRESHOLD
                        && abs(azimuth - azimuthPrev) > AZIMUTH_THRESHOLD) { // && abs(roll - rollPrev) > rollThreshold

                    if (DashplexManager.getInstance().mlocation != null) {
                        mOverlayDisplayView.setHorizontalFOV(mPreview.getHorizontalFOV());
                        mOverlayDisplayView.setVerticalFOV(mPreview.getVerticalFOV());
                        mOverlayDisplayView.setAzimuth(azimuth);
                        mOverlayDisplayView.setPitch(pitch);
                        mOverlayDisplayView.setRoll(roll);

                        // Update the OverlayDisplayView to red raw when sensor dataLogin changes,
                        // redrawing only when the camera is not pointing straight up or down
                        if (pitch <= 75 && pitch >= -75) {
                            //Log.d("issueAR", "invalidate: ");
                            mOverlayDisplayView.invalidate();
                        }
                    }

                    pitchPrev = pitch;
                    rollPrev = roll;
                    azimuthPrev = azimuth;

                }

}

computeDeviceOrientation 方法

public static float[] computeDeviceOrientation(float[] accelerometerReading, float[] magnetometerReading) {

        if (accelerometerReading == null || magnetometerReading == null) {
            return null;
        }

        final float[] rotationMatrix = new float[9];
        SensorManager.getRotationMatrix(rotationMatrix, null, accelerometerReading, magnetometerReading);

        // Remap the coordinates with the camera pointing along the Y axis.
        // This way, portrait and landscape orientation return the same azimuth to magnetic north.
        final float cameraRotationMatrix[] = new float[9];
        SensorManager.remapCoordinateSystem(rotationMatrix, SensorManager.AXIS_X,
                SensorManager.AXIS_Z, cameraRotationMatrix);

        final float[] orientationAngles = new float[3];
        SensorManager.getOrientation(cameraRotationMatrix, orientationAngles);

        // Return a float array containing [azimuth, pitch, roll]
        return orientationAngles;

}

onDraw 方法

    @SuppressLint("DrawAllocation")
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
//        Log.d("issueAR", "onDraw: ");
//        Log.d("issueAR", "mVerticalFOV: "+mVerticalFOV+" "+"mHorizontalFOV"+mHorizontalFOV);
        // Get the viewports only once
        if (!mGotViewports && mVerticalFOV > 0 && mHorizontalFOV > 0) {
            mViewportHeight = canvas.getHeight() / mVerticalFOV;
            mViewportWidth = canvas.getWidth() / mHorizontalFOV;
            mGotViewports = true;
            //Log.d("onDraw", "mViewportHeight: " + mViewportHeight);
        }

        if (!mGotViewports) {
            return;
        }

        // Set the paints that remain constant only once
        if (!mSetPaints) {
            mTextPaint.setTextAlign(Paint.Align.LEFT);
            mTextPaint.setTextSize(getResources().getDimensionPixelSize(R.dimen.canvas_text_size));
            mTextPaint.setColor(Color.WHITE);
            mOutlinePaint.setStyle(Paint.Style.STROKE);
            mOutlinePaint.setStrokeWidth(mOutline);
            mBubblePaint.setStyle(Paint.Style.FILL);
            mSetPaints = true;
        }

        // Center of view
        float x = canvas.getWidth() / 2;
        float y = canvas.getHeight() / 2;

        /*
        * Uncomment line below to allow rotation of display around the center point
        * based on the roll. However, this "feature" is not very intuitive, and requires
        * locking device orientation to portrait or changes the sensor rotation matrix
        * on device rotation. It's really quite a nightmare.
        */
        //canvas.rotate((0.0f - mRoll), x, y);

        float dy = mPitch * mViewportHeight;

        if (mNearbyPlaces != null) {

            //Log.d("OverlayDisplayView", "mNearbyPlaces: "+mNearbyPlaces.size());
            // Iterate backwards to draw more distant places first

            for (int i = mNearbyPlaces.size() - 1; i >= 0; i--) {
                NearbyPlace nearbyPlace = mNearbyPlaces.get(i);

                float xDegreesToTarget = mAzimuth - nearbyPlace.getBearingToPlace();
                float dx = mViewportWidth * xDegreesToTarget;
                float iconX = x - dx;
                float iconY = y - dy;

                if (isOverlapping(iconX, iconX).isOverlapped()) {
                    PointF point = calculateNewXY(new PointF(iconX, iconY + mViewportHeight));
                    iconX = point.x;
                    iconY = point.y;
                }
                nearbyPlace.setIconX(iconX);
                nearbyPlace.setIconY(iconY);

                Bitmap icon = getIcon(nearbyPlace.getIcon_id());
                float width = icon.getWidth() + mTextPaint.measureText(nearbyPlace.getName()) + mMargin;
                RectF recf=new RectF(iconX, iconY, width, icon.getHeight());
                nearbyPlace.setRect(recf);

                float angleToTarget = xDegreesToTarget;
                if (xDegreesToTarget < 0) {
                    angleToTarget = 360 + xDegreesToTarget;
                }

                if (angleToTarget >= 0 && angleToTarget < 90) {
                    nearbyPlace.setQuadrant(1);
                    mQuad1Places.add(nearbyPlace);
                } else if (angleToTarget >= 90 && angleToTarget < 180) {
                    nearbyPlace.setQuadrant(2);
                    mQuad2Places.add(nearbyPlace);
                } else if (angleToTarget >= 180 && angleToTarget < 270) {
                    nearbyPlace.setQuadrant(3);
                    mQuad3Places.add(nearbyPlace);
                } else {
                    nearbyPlace.setQuadrant(4);
                    mQuad4Places.add(nearbyPlace);
                }


                //Log.d("TAG", " -  X: " + iconX + " y: " + iconY + " angle: " + angleToTarget + " display: " + nearbyPlace.getIcon_id());

            }

            drawQuadrant(mQuad1Places, canvas);
            drawQuadrant(mQuad2Places, canvas);
            drawQuadrant(mQuad3Places, canvas);
            drawQuadrant(mQuad4Places, canvas);
        }

    }

它不包含完整的代码,但你可能会理解如何使用滚动的音高和方位角。祝你好运