1

I've got a custom view, which is essentially a grid drawn onto a canvas, for which I have implemented panning and zooming. These work fine, but I also want to be able to find the grid coordinates of a click.

In order to do this, I must compensate for both the amount that the view has been panned, as well as the amount that it has been zoomed/scaled. This is what I am having trouble with.

To compensate for the amount it has been panned I keep track of all translations (or displacement) that have occurred in PointF dspl. In the onTouchEvent(MotionEvent event) method of my custom view I switch on event.getAction() & MotionEvent.ACTION_MASK and in the case MotionEvent.ACTION_DOWN set the starting point of the event as well as the starting displacement and some other self explanatory things:

case MotionEvent.ACTION_DOWN:
    //Remember where we started

    start.set(event.getX(), event.getY());   //set starting point of event
    last.set(event.getX(),event.getY());     //set coordinates of last point touched
    startDspl.set(dspl.x,dspl.y);            //set starting displacement to current displacement

    //save the id of this pointer
    activePointerId = event.getPointerId(0);

    savedMatrix.set(matrix);                 //save the current matrix
    mode = DRAG;

    break;

and then in the caseMotionEvent.ACTION_UP I do the following:

 case MotionEvent.ACTION_UP:
   mode = NONE;
   activePointerId = INVALID_POINTER_ID;

   distance = Math.sqrt( (start.x - last.x)*(start.x - last.x) + 
                         (start.y - last.y)*(start.y - last.y));

   if( distance < 5){
        //need to translate x and y due to panning and zooming

        int [] coord = getClickCoordinates(start.x,start.y);
        Toast.makeText(context, " x = " + coord[0] + ", y = " + coord[1], 
        Toast.LENGTH_SHORT).show();
    }

and finally the method where I get the coordinates:

public int[] getClickCoordinates(float clickX, float clickY) {

    float x = (clickX - startDspl.x)/(cellWidth*scaleFactor);
    float y = nRows - (clickY - startDspl.y)/(cellHeight*scaleFactor);

    return new int[] { (int) x, (int) y };
}

(Here scaleFactor is the amount that the view has been scaled overall). This method does not work for panning, as I expected it should, and I've no idea how to modify it to properly account for zooming.

I would greatly appreciate any help as I've been struggling with this for quite a long time now, and yes I am aware of this question, which is a little different from what I want to do.

Thanks!

Community
  • 1
  • 1
Rookatu
  • 1,487
  • 3
  • 21
  • 50
  • This question was answered [here](https://stackoverflow.com/a/17142856/1393860). It came up as a part of a similar question. – Rookatu Jul 20 '13 at 01:40

0 Answers0