10

i want to rotate and scale the image on multi touch event, i am able to drag, scale the image but i can't understand the rotation of image. i am facing problem so please help me asap. my code is there

    public class Touch extends Activity implements OnTouchListener {
       private static final String TAG = "Touch";
      // These matrices will be used to move and zoom image
       Matrix matrix = new Matrix();
   Matrix matrix1 = new Matrix();
   Matrix savedMatrix = new Matrix();
   Matrix savedMatrix2 = new Matrix();
   // We can be in one of these 3 states
   static final int NONE = 0;
   static final int DRAG = 1;
   static final int ZOOM = 2;
   int mode = NONE;
   float oldscale =0;
   // Remember some things for zooming
   PointF start = new PointF();
   PointF mid = new PointF();
   float oldDist = 1f;

   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
      ImageView view = (ImageView) findViewById(R.id.imageView2);
      view.setOnTouchListener(this);

      ImageView view1 = (ImageView) findViewById(R.id.imageView2);
      view1.setOnTouchListener(this);

      // ...
      // Work around a Cupcake bug
      matrix.setTranslate(1f, 1f);
      matrix1.setTranslate(1f, 1f);
      view.setImageMatrix(matrix);
      view1.setImageMatrix(matrix1);
   }

   @Override
   public boolean onTouch(View v, MotionEvent rawEvent) {
      WrapMotionEvent event = WrapMotionEvent.wrap(rawEvent);
      // ...
      ImageView view = (ImageView) v;

      // Dump touch event to log
       dumpEvent(event);

      // Handle touch events here...
       double r = Math.atan2(event.getX() - 400 / 2,
            400 / 2 - event.getY());
       int rotation = (int) Math.toDegrees(r);
       float newRot = new Float(rotation);

      switch (event.getAction() & MotionEvent.ACTION_MASK) {

      case MotionEvent.ACTION_DOWN:
         savedMatrix.set(matrix);
         start.set(event.getX(), event.getY());
         Log.d(TAG, "mode=DRAG");
         mode = DRAG;
         break;
       case MotionEvent.ACTION_POINTER_DOWN:
         oldDist = spacing(event);
         Log.d(TAG, "oldDist=" + oldDist);
         if (oldDist > 10f) {
            savedMatrix.set(matrix);
            midPoint(mid, event);
            mode = ZOOM;
            Log.d(TAG, "mode=ZOOM");

         }
         break;
      case MotionEvent.ACTION_UP:
      case MotionEvent.ACTION_POINTER_UP:
         mode = NONE;
         Log.d(TAG, "mode=NONE");
         break;
      case MotionEvent.ACTION_MOVE:
          matrix.postRotate(15);
         if (mode == DRAG) {
            // ...
            matrix.set(savedMatrix);
            matrix.postTranslate(event.getX() - start.x,
                  event.getY() - start.y);
         }
         else if (mode == ZOOM) {
            float newDist = spacing(event);
            Log.d(TAG, "newDist=" + newDist);
            if (newDist > 10f) {
               matrix.set(savedMatrix);
               float scale = newDist / oldDist;
               matrix.postScale(scale, scale, mid.x, mid.y);
               Log.e("scale | mid.x | mid.y", scale + " " +mid.x + " " + mid.y);

            }
         }
         break;
      }
      view.setImageMatrix(matrix);
      return true; // indicate event was handled
   }

   /** Show an event in the LogCat view, for debugging */
   private void dumpEvent(WrapMotionEvent event) {
      // ...
      String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE",
            "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
      StringBuilder sb = new StringBuilder();
      int action = event.getAction();
      int actionCode = action & MotionEvent.ACTION_MASK;
      sb.append("event ACTION_").append(names[actionCode]);
      if (actionCode == MotionEvent.ACTION_POINTER_DOWN
            || actionCode == MotionEvent.ACTION_POINTER_UP) {
         sb.append("(pid ").append(
               action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
         sb.append(")");
      }
      sb.append("[");
      for (int i = 0; i < event.getPointerCount(); i++) {
         sb.append("#").append(i);
         sb.append("(pid ").append(event.getPointerId(i));
         sb.append(")=").append((int) event.getX(i));
         sb.append(",").append((int) event.getY(i));
         if (i + 1 < event.getPointerCount())
            sb.append(";");
      }
      sb.append("]");
      Log.d(TAG, sb.toString());
   }

   /** Determine the space between the first two fingers */
   private float spacing(WrapMotionEvent event) {
      // ...
      float x = event.getX(0) - event.getX(1);
      float y = event.getY(0) - event.getY(1);
      return FloatMath.sqrt(x * x + y * y);
   }

   /** Calculate the mid point of the first two fingers */
   private void midPoint(PointF point, WrapMotionEvent event) {
      // ...
      float x = event.getX(0) + event.getX(1);
      float y = event.getY(0) + event.getY(1);
      point.set(x / 2, y / 2);
   }
}

so please provide me exact solution for this problem.

Ramesh Sudrasana
  • 101
  • 1
  • 1
  • 5

1 Answers1

11
   float[] lastEvent = null;
   float d = 0f;
   float newRot = 0f;
   @Override
   public boolean onTouch(View v, MotionEvent event) {
      ImageView view = (ImageView) v;

      // Dump touch event to log
      dumpEvent(event);

      // Handle touch events here...
      switch (event.getAction() & MotionEvent.ACTION_MASK) {
      case MotionEvent.ACTION_DOWN:
         savedMatrix.set(matrix);
     start.set(event.getX(), event.getY());
     if (Constant.TRACE) Log.d(TAG, "mode=DRAG");
     mode = DRAG;
     lastEvent = null;
     break;
  case MotionEvent.ACTION_POINTER_DOWN:
     oldDist = spacing(event);         
     savedMatrix.set(matrix);
     midPoint(mid, event);
     mode = ZOOM;
     if (Constant.TRACE) Log.d(TAG, "mode=ZOOM");

     lastEvent = new float[4];
     lastEvent[0] = event.getX(0);
     lastEvent[1] = event.getX(1);
     lastEvent[2] = event.getY(0);
     lastEvent[3] = event.getY(1);
     d = rotation(event);
     break;
  case MotionEvent.ACTION_UP:
  case MotionEvent.ACTION_POINTER_UP:
     mode = NONE;
     lastEvent = null;
     if (Constant.TRACE) Log.d(TAG, "mode=NONE");         
     break;
  case MotionEvent.ACTION_MOVE:
     if (mode == DRAG) {
        // ...
        matrix.set(savedMatrix);
        matrix.postTranslate(event.getX() - start.x, event.getY() - start.y);
     }
     else if (mode == ZOOM && event.getPointerCount()==2) {
        float newDist = spacing(event);
        if (Constant.TRACE) Log.d(TAG, "Count=" + event.getPointerCount());
        if (Constant.TRACE) Log.d(TAG, "newDist=" + newDist);
        matrix.set(savedMatrix);
        if (newDist > 10f) {              
           float scale = newDist / oldDist;
           matrix.postScale(scale, scale, mid.x, mid.y);
        } 
        if (lastEvent!=null){
            newRot = rotation(event); 
            if (Constant.TRACE) Log.d("Degreeeeeeeeeee", "newRot="+(newRot));
            float r = newRot-d;
            matrix.postRotate(r, imgView.getMeasuredWidth()/2, imgView.getMeasuredHeight()/2);  
        }
     }
     break;
  }

  view.setImageMatrix(matrix);
  return true; // indicate event was handled

}

/** Determine the degree between the first two fingers */
   private float rotation(MotionEvent event) {  
       double delta_x = (event.getX(0) - event.getX(1));
       double delta_y = (event.getY(0) - event.getY(1));
       double radians = Math.atan2(delta_y, delta_x);       
       if (Constant.TRACE) Log.d("Rotation ~~~~~~~~~~~~~~~~~", delta_x+" ## "+delta_y+" ## "+radians+" ## "
                        +Math.toDegrees(radians));
       return (float) Math.toDegrees(radians);
   }

Try this code, but remember some old phone have problem with rotation..

Vladimir Ivanov
  • 42,730
  • 18
  • 77
  • 103
user430926
  • 4,017
  • 13
  • 53
  • 77
  • 1
    I have tried this above code it's good but image is not rotating around it's own axis, it needs to be rotate around it's center Point but because of scaling it is displayed at wrong position.how to find the relative coordinates for it. – strike Sep 21 '12 at 10:52
  • @strike, you can save the current translate of image and calculate the center point.and don't forget about scaling. – someUser Nov 07 '12 at 21:28
  • Why that code is not working in all the phones? I've tried with a Nexus 4 and it works, but not with a Nexus One. – nano Mar 21 '13 at 08:39