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
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.
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
Post a Comment