繁体   English   中英

位图围绕错误的枢轴旋转

[英]Bitmap rotating about the wrong pivot

我在我的地图应用程序中添加了指南针叠加层。 我决定创建一个相当复杂的罗盘玫瑰,并在覆盖的构造函数中将其绘制到位图上一次,而不是在每次绘制时。 在叠加层的绘图中,我只是根据磁传感器的值使用Matrix旋转位图。

简而言之,当旋转角度不是90度,180度或270度时,它是不正确的-它似乎不围绕中心旋转。

我创建了一个最小的示例,该示例再现了下面显示的问题以及我看到的0、45和90度旋转的屏幕截图。 覆盖形状比真实版本要简单得多,并且一些值已经过硬编码以减小帖子大小,但这使用了与真实应用相同的原理。

public class BasicMapOverlayActivity extends MapActivity {

    private MapController mMapCtrlr;
    private MapView mMapVw;
    private int mStartLat = 53500000;
    private int mStartLon = -3000000; 
    private float mBearing = 0.0f;
    private static final int COMPASS_OVL_SIZE = 100;
    private Bitmap mCompassRoseBmap;
    private Canvas mCompassRoseCanvas;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mMapVw = (MapView) findViewById(R.id.map);
        mMapCtrlr = mMapVw.getController();
        mMapCtrlr.setZoom(14);
        mMapVw.setSatellite(true);
        mMapVw.setBuiltInZoomControls(true);
        GeoPoint startGpt = new GeoPoint(mStartLat, mStartLon);
        mMapCtrlr.setCenter(startGpt);
        mCompassRoseCanvas = new Canvas();
        mCompassRoseBmap = Bitmap.createBitmap(COMPASS_OVL_SIZE, COMPASS_OVL_SIZE, Bitmap.Config.ARGB_8888);
        mCompassRoseCanvas.setBitmap(mCompassRoseBmap);
        List<Overlay> listOfOverlays = mMapVw.getOverlays();
        CompassOverlay compassOverlay = new CompassOverlay(mCompassRoseCanvas);
        listOfOverlays.add(compassOverlay);
    }
    public void myClickHandler(View target) {

        switch (target.getId()) {
            case R.id.TurnZeroButton:
                mBearing = 0;
                break;
            case R.id.TurnThirtyButton:
                mBearing = 30;
                break;
            case R.id.Turn45Button:
                mBearing = 45;
                break;
            case R.id.TurnNinetyButton:
                mBearing = 90;
                break;
            case R.id.Turn180Button:
                mBearing = 180;
                break;
        }
        EditText et = (EditText) findViewById(R.id.editText1);
        NumberFormat formatter = new DecimalFormat("##0");
        et.setText(formatter.format(mBearing));
        mMapVw.invalidate();
    }
    @Override
    protected boolean isRouteDisplayed() {return false;}

    public class CompassOverlay extends com.google.android.maps.Overlay {

        private Paint overlayPaint;
        private RectF oRec;

        public CompassOverlay(Canvas canvas) {
            super();
            createRose(canvas, COMPASS_OVL_SIZE);
        }

        public void createRose(Canvas canvas, int overlaySize) {

            float scale = (float) overlaySize;
            canvas.scale(scale, scale);
            overlayPaint = new Paint();
            overlayPaint.setStyle(Paint.Style.FILL_AND_STROKE);
            overlayPaint.setColor(Color.YELLOW);
            overlayPaint.setAntiAlias(true);
            oRec = new RectF();
            oRec.set(0.0f, 0.0f, 1.0f, 1.0f);
            // draw rectangle edges and diagonals
            canvas.drawLine(oRec.left, oRec.top, oRec.right, oRec.bottom, overlayPaint);
            canvas.drawLine(oRec.left, oRec.bottom, oRec.right, oRec.top, overlayPaint);
            canvas.drawLine(oRec.left, oRec.top, oRec.right, oRec.top, overlayPaint);
            canvas.drawLine(oRec.right, oRec.top, oRec.right, oRec.bottom, overlayPaint);
            canvas.drawLine(oRec.right, oRec.bottom, oRec.left, oRec.bottom, overlayPaint);
            canvas.drawLine(oRec.left, oRec.bottom, oRec.left, oRec.top, overlayPaint);
            // draw red vertical line as a direction indicator
            overlayPaint.setColor(Color.RED);
            canvas.drawLine(0.5f, oRec.top, 0.5f, oRec.bottom/2, overlayPaint);// vertical line
            overlayPaint.setColor(Color.YELLOW);
        }
        @Override
        public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when) {

            Bitmap rBitmap = rotateCompassBitmap(mBearing);
            canvas.drawBitmap(rBitmap, 160, 70, null);
            rBitmap.recycle();
            return false;
        }

        private Bitmap rotateCompassBitmap(float rotationDegrees) {
            Matrix matrix = new Matrix();
            matrix.postRotate(rotationDegrees);
            Bitmap rotatedBitmap = Bitmap.createBitmap(mCompassRoseBmap, 0, 0,
                     mCompassRoseBmap.getWidth(), mCompassRoseBmap.getHeight(), matrix, true); 
            return  rotatedBitmap;
        }
    }
}

布局只是一个简单的地图,其中包含一些按钮,这些按钮通过clickListener进行旋转。 所应用的旋转显示在EditText中。

零旋转 零旋转

45度 45度

90度 90度

我们将不胜感激,因为我是第一个承认图形方面我不是世界上最好的人。

使用postRotate旋转一个点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM