简体   繁体   English

如何在Android中计算缩放画布的坐标

[英]How to calculate coordinates of scaled canvas in Android

I am working with Android project. 我正在使用Android项目。 I have trouble with understand how to use ScaleDetector and Canvas. 我无法理解如何使用ScaleDetector和Canvas。

I have list called printTable with Rectangles. 我有一个名为带有矩形的printTable的列表。 I draw every Rectangle on screen in method onDraw(). 我在屏幕上使用onDraw()方法绘制每个Rectangle。 Then I have second list called listPointer with Rectangles and id's of Rectangles. 然后,我有了第二个名为listPointer的列表,其中包含Rectangles和ID为Rectangles的列表。 I am checking that list onTouchEvent for rectangle that is draw on screen. 我正在检查屏幕上绘制的矩形的onTouchEvent列表。 If Rectangle contains X,YI print information about id of clicked Rectangle. 如果Rectangle包含X,YI将输出有关单击的Rectangle的ID的信息。

The problem is how to calculate my X,Y when I move my canvas or scale it? 问题是当我移动画布或缩放画布时如何计算X,Y?

public class Painter extends View {

    //
    private static final int INVALID_POINTER_ID = -1;
    private float mPosX;
    private float mPosY;

    private float mLastTouchX;
    private float mLastTouchY;
    private int mActivePointerId = INVALID_POINTER_ID;

    private ScaleGestureDetector mScaleDetector;
    private float mScaleFactor = 1.f;
    //

    Paint paint = new Paint();

    List<Table> printTable = new ArrayList<Table>(); // lista wyświetlanych stolików

    //
    List<Pointer> listPointer = new ArrayList<Pointer>();
    //

    public Painter(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public Painter(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
    }

    private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            mScaleFactor *= detector.getScaleFactor();

            // Don't let the object get too small or too large.
            mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 10.0f));

            invalidate();
            return true;
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        // Let the ScaleGestureDetector inspect all events.
        mScaleDetector.onTouchEvent(ev);

        final int action = ev.getAction();
        switch (action & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN: {
            final float x = ev.getX();
            final float y = ev.getY();

            mLastTouchX = x;
            mLastTouchY = y;
            mActivePointerId = ev.getPointerId(0);
            for(int i = 0; i<listPointer.size(); i++)
            {
                if(listPointer.get(i).getRectangle().contains((int)(Math.round(x)), (int)(Math.round(y))))
                {
                    if(listPointer.get(i).getIsItTable())
                    {
                        Log.e("Exc", "Stolik "+listPointer.get(i).getId());
                    }
                    else
                    {
                        Log.e("Exc", "Button "+listPointer.get(i).getId());
                    }
                }
            }
            break;
        }

        case MotionEvent.ACTION_MOVE: {
            final int pointerIndex = ev.findPointerIndex(mActivePointerId);
            final float x = ev.getX(pointerIndex);
            final float y = ev.getY(pointerIndex);

            // Only move if the ScaleGestureDetector isn't processing a gesture.
            if (!mScaleDetector.isInProgress()) {
                final float dx = x - mLastTouchX;
                final float dy = y - mLastTouchY;

                mPosX += dx;
                mPosY += dy;

                invalidate();
            }

            mLastTouchX = x;
            mLastTouchY = y;

            break;
        }

        case MotionEvent.ACTION_UP: {
            mActivePointerId = INVALID_POINTER_ID;
            break;
        }

        case MotionEvent.ACTION_CANCEL: {
            mActivePointerId = INVALID_POINTER_ID;
            break;
        }

        case MotionEvent.ACTION_POINTER_UP: {
            final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) 
                    >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
            final int pointerId = ev.getPointerId(pointerIndex);
            if (pointerId == mActivePointerId) {
                // This was our active pointer going up. Choose a new
                // active pointer and adjust accordingly.
                final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
                mLastTouchX = ev.getX(newPointerIndex);
                mLastTouchY = ev.getY(newPointerIndex);
                mActivePointerId = ev.getPointerId(newPointerIndex);
            }
            break;
        }
        }

        return true;
    }

    //

    public Painter(Context context) {

        this(context, null, 0);

        paint.setColor(Color.BLACK);

        List<Table> printTable = Bridge.getTables(getContext()); 

    }

    @SuppressLint("DrawAllocation")
    @Override
    public void onDraw(Canvas canvas) {

        super.onDraw(canvas);
            Rect rect = null;
            RectF rectF = null;
            // czyszczenie tablicy
            listPointer.clear();

            for(int j = 0; j<printTable.size(); j++)
            {
                Table item = printTable.get(j);
                // Obsługa rozciągania

                canvas.save();
                Log.d("DEBUG", "X: "+mPosX+" Y: "+mPosY);
                canvas.translate(mPosX, mPosY);
                canvas.scale(mScaleFactor, mScaleFactor);

                // dodaje do tablicy stołów
                paint.setColor(getResources().getColor(R.color.green));
                rect = new Rect(item.getX1(), item.getY1(), item.getX2(), item.getY2());
                rectF = new RectF(rect);
                canvas.drawRoundRect(rectF, 0,0, paint);
                listPointer.add(new Pointer(rect, true, j));

                canvas.restore();
            }
    }

Get the matrix for the view. 获取视图的矩阵。 That should have all of the scaling and translating in it. 那应该包含所有缩放和平移。 Then multiply your x,y coordinates as a vector by the matrix used to scale the view. 然后将x,y坐标作为向量乘以用于缩放视图的矩阵。 That should convert prescaled/pretranslated coordinates into scaled coordinates. 那应该将预缩放/预转换的坐标转换为缩放坐标。 If it would require fewer multiplies, you can also multiply the post-scale coordiantes by the inverse of that matrix to get prescale coordinates. 如果需要较少的乘法,则还可以将后缩放坐标与该矩阵的逆值相乘,以获得预缩放坐标。

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

相关问题 Android:使用缩放和平移的画布获取正确的坐标 - Android: Get correct coordinates with scaled and translated canvas 如何使MotionEvent的坐标与缩放画布的坐标相匹配? - How do I make the coordinates of MotionEvent match the ones of a scaled canvas? Android Java,在缩放的画布上绘制 - Android Java, draw on a scaled canvas 如何修复 Android 中缩放 canvas 的错误坐标 - how to fix the wrong coordinates of zoomed canvas in Android 如何在Android中正确地将像素坐标转换为画布坐标? - How do I correctly translate pixel coordinates to canvas coordinates in Android? 如何将归一化设备坐标转换为 Android 上 canvas 的像素坐标? - How to convert Normalized Device Coordinates to pixel coordinates for canvas on Android? 从缩放的画布上获取精确的触摸位置(从屏幕坐标到画布坐标) - To get exact touch position (from screen coordinates to canvas coordinates) from a scaled canvas Android使用画布绘制比例位图的一部分 - Android draw a part of scaled bitmap using canvas Android在画布上获得旋转缩放文本的边界 - Android get bounds of rotated,scaled text on canvas 如何使用位图在缩放的画布上绘制线,圈 - How to draw line, circle on scaled canvas with bitmap
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM