2016-03-25 3 views
1

Im создание приложения для рисования, и у меня есть представление, которое использует холст для рисования. Я масштабирую изображение, используя матрицу, и когда изображение увеличено, и есть событие касания, я пытаюсь получить обратную матрицу, а затем сопоставить точки с помощью обратной матрицы, чтобы получить точки, которые находятся на холсте, от пункт motionevent указывает, но не соответствует тому, как это должно быть, и задается вопросом, что я делаю неправильно, чтобы получить местоположение холста с экрана.Получить местоположение на холсте из местоположения события движения при масштабировании с использованием матрицы

public class CustomDrawableView extends View { 
    private Paint mBitmapPaint; 
    private ShapeDrawable mDrawable; 
    private ScaleGestureDetector detector; 
    Matrix drawMatrix; 
    Bitmap bm; 

    @Override 
    protected void onDraw(Canvas canvas) { 
      super.onDraw(canvas); 
      canvas.save();   
      canvas.drawBitmap(bm, drawMatrix, mBitmapPaint);   
      mDrawable.draw(canvas); 
      canvas.restore();  
    } 
    public Pair<Float,Float> GetRealValues(float eventX, float eventY){   
     Matrix inverse = new Matrix(); 
     drawMatrix.invert(inverse); 
     float[] point = {eventX,eventY}; 
     inverse.mapPoints(point);  
     return new Pair<>(point[0],point[1]); 
    } 

    @Override 
    //reads motions and calls methods to set starting and ending points and to 
    //draw canvas depending on the motion 
    public boolean onTouchEvent(MotionEvent event) { 
     //get the canvas location from the MotionEvent location  
     Pair<Float,Float> realvals = GetRealValues(event.getX(),event.getY()); 
     //drawing mode where you can draw or zoom in on canvas 
      if(drawing) { 
       //not zooming mode where you draw on canvas 
       if (!zoom) { 
        switch (event.getAction() & MotionEvent.ACTION_MASK) {        
         case MotionEvent.ACTION_DOWN: 
          //do stuff 
          break;        
         case MotionEvent.ACTION_MOVE: 
          //do stuff 
          break; 
         case MotionEvent.ACTION_UP: 
          //do stuff 
          break; 
         case MotionEvent.ACTION_POINTER_UP: 
          break; 
        } 
     } 
     //zoom mode where you can scale the canvas 
      if (zoom) { 
       detector.onTouchEvent(event);       
       invalidate(); 
      } 
     }   
    return true; 
} 



    public class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { 
     private float MIN_ZOOM = 1f; 
     private float MAX_ZOOM = 10f;  

     @Override 
     public boolean onScale(ScaleGestureDetector detector) { 
      Matrix transformationMatrix = new Matrix(); 
      scaleFactor *= detector.getScaleFactor(); 
      float tscale = detector.getScaleFactor(); 
      if(scaleFactor < MIN_ZOOM || scaleFactor > MAX_ZOOM){ 
       float prescaleFactor = scaleFactor/tscale; 
       scaleFactor = Math.max(MIN_ZOOM, Math.min(scaleFactor, MAX_ZOOM)); 
       tscale = scaleFactor/prescaleFactor; 
      } 
      transformationMatrix.postScale(tscale, tscale);    
      drawMatrix.postConcat(transformationMatrix); 
      return true; 
    } 
} 

ответ

0

Найден ответ. Мой OnDraw метод должен быть, как этот

@Override 
protected void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 
     canvas.save();   
     float[] mvals = new float[9]; 
     drawMatrix.getValues(mvals); 
     canvas.translate(mvals[Matrix.MTRANS_X], mvals[Matrix.MTRANS_Y]); 
     canvas.scale(mvals[Matrix.MSCALE_X], mvals[Matrix.MSCALE_Y]); 
     canvas.drawBitmap(bm, 0, 0, mBitmapPaint); 
     mDrawable.draw(canvas); 
     canvas.restore(); 
} 

Я не знаю, почему мне нужно переводить и масштабировать холст индивидуально для того, чтобы обратная матрица дать мне правильные точки холста из точек соприкосновения, я м предполагает, что

canvas.drawBitmap(bm, drawMatrix, mBitmapPaint); 

округляет значение матрицы к Интс, поскольку точки холста я получил от отображения точек на обратной матрице были просто слегка при рисовании на холсте таким образом.