Getting correct coordinates after pinch zoom (drawing line) Android Canvas -


i trying draw line following users finger(touch). quite easy task implement if there no scaling.
drawing without scaling works here screenshot

enter image description here

works well. can see.

but if scale canvas begins draw points margin/measurement error/tolerance. seems have not taken value in advance while calculating scaled touch points, have tried lot of different formulas, nothing helped.

here result of zooming canvas. enter image description here

it seems problem in delta value have take consideration

because if use version of scale function works scales left top corner.

canvas.scale(mscalefactor, mscalefactor);  

with scaling

canvas.scale(mscalefactor, mscalefactor, scalepointx, scalepointy); 

multitouch zoom (pinch) works coordinates not correct.

please solve problem, seems have take these scalepointx, scalepointy variables when calculating scaled x , y.

here code. highly appreciated.

private void initworkspace(context context) {         mpaint = new paint();         mscaledetector = new scalegesturedetector(context, new scalelistener());         mrect = new rect();         mpath = new path();         mpaint.setantialias(true);         mpaint.setcolor(color.black);         mpaint.setstyle(paint.style.stroke);         mpaint.setstrokejoin(paint.join.round);         mpaint.setstrokewidth(10f);     }     @override     protected void ondraw(canvas canvas) {         super.ondraw(canvas);         canvas.getclipbounds(mrect);         canvas.save();         canvas.scale(mscalefactor, mscalefactor, scalepointx, scalepointy);         canvas.translate(mrect.top,mrect.left);         canvas.drawpath(mpath, mpaint);         canvas.restore();      }     // when action_down start touch according x,y values     private void starttouch(float x, float y) {         mpath.moveto(x, y);         mx = x;         = y;     }      // when action_move move touch according x,y values     private void movetouch(float x, float y) {         float dx = math.abs(x - mx);         float dy = math.abs(y - my);         if (dx >= tolerance || dy >= tolerance) {             mpath.quadto(mx, my, (x + mx) / 2, (y + my) / 2);             mx = x;             = y;         }     }      public void clearcanvas() {         mpath.reset();         invalidate();     }      // when action_up stop touch     private void uptouch() {         mpath.lineto(mx, my);     }      @override     public boolean ontouchevent(motionevent ev) {         // let scalegesturedetector inspect events.         mscaledetector.ontouchevent(ev);          final int action = ev.getaction();         log.e("touch","real x :" + ev.getx() + " real y : " + ev.gety());         log.e("touch","rect top :" + mrect.top + " rect left : " + mrect.left + " rect right : " + mrect.right + " rect bottom :" + mrect.bottom);         final float scaledx = ev.getx()/mscalefactor+mrect.left*mscalefactor;         final float scaledy = ev.gety()/mscalefactor+mrect.top*mscalefactor;         switch (action & motionevent.action_mask) {             case motionevent.action_down: {                  /*final float x = (ev.getx() - scalepointx) / mscalefactor;                 final float y = (ev.gety() - scalepointy) / mscalefactor;                 cx = x - mposx + scalepointx; // canvas x                 cy = y - mposy + scalepointy; // canvas y*/                  // remember started                 mlasttouchx = scaledx;                 mlasttouchy = scaledy;                 log.e("down","scale factor : " + mscalefactor);                 log.e("down","x : " +mlasttouchx + " y :" + mlasttouchy + " scalepointx : " + scalepointx + " scalepointy : " + scalepointy );                  log.e("down","last x : " + mlasttouchy + " last y :" + mlasttouchy);                 starttouch(mlasttouchx, mlasttouchy);                 invalidate();                 break;             }             case motionevent.action_move: {                /* final float x = (ev.getx() - scalepointx) / mscalefactor;                 final float y = (ev.gety() - scalepointy) / mscalefactor;                 cx = x - mposx + scalepointx; // canvas x                 cy = y - mposy + scalepointy; // canvas y                  // move if scalegesturedetector isn't processing gesture.                 if (!mscaledetector.isinprogress()) {                     final float dx = x - mlasttouchx; // change in x                     final float dy = y - mlasttouchy; // change in y                      mposx += dx;                     mposy += dy;                      invalidate();                 }*/                 log.e("action_move","scale factor : " + mscalefactor);                 log.e("action_move","x : " + scaledx + " y :" + scaledy + " cx : " + cx + " cy : " + cy );                 log.e("action_move","last x : " + mlasttouchx + " last y :" + mlasttouchy);                 mlasttouchx = scaledx;                 mlasttouchy = scaledy;                 movetouch(scaledx, scaledy);                 invalidate();                 break;              }             case motionevent.action_up: {                 mlasttouchx = 0;                 mlasttouchy = 0;                 uptouch();                 invalidate();             }         }         return true;     }      private class scalelistener extends scalegesturedetector.simpleonscalegesturelistener {         @override         public boolean onscale(scalegesturedetector detector) {             mscalefactor *= detector.getscalefactor();             scalepointx = detector.getfocusx();             scalepointy = detector.getfocusy();             // don't let object small or large.             mscalefactor = math.max(0.1f, math.min(mscalefactor, 10.0f));             mscalefactor = (mscalefactor < 1 ? 1 : mscalefactor);             invalidate();             return true;         }     } 


Comments

Popular posts from this blog

c# - Binding a comma separated list to a List<int> in asp.net web api -

Delphi 7 and decode UTF-8 base64 -

html - Is there any way to exclude a single element from the style? (Bootstrap) -