7

I am trying to rotate image single round from it's center point but I am not able to stop at desire position as I can do rotation but I want to stop rotation after 360'(1 round).

public class RotateRoundActivity extends Activity implements OnTouchListener
{

    private ImageView dialer;
    //private float y=0;
    private float x=0;

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

    @Override
    public boolean onTouch(View v, MotionEvent event) {
    //  double r=Math.atan2(event.getX()-dialer.getWidth()/2, dialer.getHeight()/2-event.getY());

        double r=Math.atan2(event.getX()-dialer.getWidth()/2, dialer.getHeight()/2-event.getY());
        int rotation=(int)Math.toDegrees(r);
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                break;
            case MotionEvent.ACTION_MOVE:
                x=event.getX();
              //  y=event.getY();
                updateRotation(rotation);
                break;
            case MotionEvent.ACTION_UP:
                break;
        }//switch       

        return true;
    }

Rotation method@

    private void updateRotation(double rot){
        float newRot=new Float(rot);
        Bitmap bitmap=BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher);
        Matrix matrix=new Matrix();
        matrix.postRotate(newRot,bitmap.getWidth(),bitmap.getHeight());
        Log.i("demo===>", "matrix==>" + matrix);
     //   Log.i("demo===", "y===>" + y);
        Log.i("demo===", "x===>" + x);

        if(x>250){
            Bitmap reDrawnBitmap=Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);
            dialer.setImageBitmap(reDrawnBitmap);
        }
        else{
            Bitmap reDrawnBitmap=Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);
            dialer.setImageBitmap(reDrawnBitmap);
        }
    }

}

Your suggestions are appreciable.

Maulik
  • 3,316
  • 20
  • 31

2 Answers2

3

You have to save previous rot value. And add check in updateRotation method if previousRot is at the left of 360' degrees and rot is at the right of 360' degrees then we made 1 round and need stop rotating.

Sample code for clockwise case

if (previousRot >= 300 && previousRot <= 360 && rot >= 0 && rot <= 60) {
    rot = 359.99; // or here can be 360'
}

For counter clockwise case it is almost the same, but the values swapped

if (previousRot >= 0 && previousRot <= 60 && rot >= 300 && rot <= 360) {
    rot = 0;
}

This code will stop rotation. From the beginning previousRot should be 0 for clockwise case and 359.99 for counter clockwise


Another approach is to add one more variable to store total traveled angle. From the beginning traveledAngle have to be equal to 0. And if you're rotating in clockwise direction you have to increase it by the difference between rot and previousRot. When rotating counter clockwise decrease it by the same value.

traveledAngle += rot - previousRot;

When traveledAngle becomes greater than 360' you need to stop rotating in clockwise direction, and when it becomes less than 0, you need to stop rotating in counter clockwise direction.

vasart
  • 6,692
  • 38
  • 39
  • How can I get the angle more than 360' degree? It will be increase from 1' to 360'. after 360' it takes 1' degree. – Maulik Jul 05 '12 at 09:36
  • That's right! For clockwise direction `previousRot` should be 350-360', and `rot` should be about 0-10'. But this numbers are given only for example, it may be 300-360' and 0-60'. The main idea is using `previousRot` value – vasart Jul 05 '12 at 10:01
  • Okay. but how can I stop rotation using previousRot? if I am at 1' after one rotation and my previousRot value is 360' then? And what should be logic for anticlockwise? – Maulik Jul 05 '12 at 10:39
  • Added one more approach to solve the problem using `traveledAngle` – vasart Jul 05 '12 at 11:09
  • I like your concept and logic for traveledAngle and rot angle. I have been trying to solve the issue to stop rotation for two days after your comment. And I almost get solution for this issue. Thank you. – Maulik Jul 10 '12 at 06:23
  • I hadn't get the exact solution but yes almost I was very close to that. so I am accepting your answer. – Maulik Jul 12 '13 at 10:56
2

I have used your demo and added some logic, the newer demo is as below:

public class RotateRoundActivity extends Activity implements OnTouchListener {
    float rot1=0.0F, rot2=0.0F;
    boolean clockwise, rotationDone = false, halfrotated = false;
    int rotcall=0;

    private ImageView dialer;
    //private float y=0;
    private int x=0;
    //private int y=0;

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

    @Override
    public boolean onTouch(View v, MotionEvent event) {
    //  double r=Math.atan2(event.getX()-dialer.getWidth()/2, dialer.getHeight()/2-event.getY());
        double r=Math.atan2(event.getX()-dialer.getWidth()/2, dialer.getHeight()/2-event.getY());
        int rotation=(int)Math.toDegrees(r);
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                break;
            case MotionEvent.ACTION_MOVE:
                x=(int) event.getX();
                //y=(int) event.getY();
                updateRotation(rotation);
                break;
            case MotionEvent.ACTION_UP:
                break;
        }//switch       

        return true;
    }

    private void updateRotation(double rot){
        float newRot = new Float(rot);

        rotcall++;
        if(rotcall == 1)
            rot1 = new Float(rot);
        if(rotcall == 2)
            rot2 = new Float(rot);
        if(rot1 != 0.0F && rot2 != 0.0F)
            if(rot1 < rot2)
                clockwise = true;
            else
                clockwise = false;
        System.out.println("Rotate :: "+newRot);

        if(clockwise && rot1>=0 ) {
            if(newRot < 0)
                halfrotated = true;
            if(halfrotated && newRot > 0)
                rotationDone = true;
            if(rotationDone)
                newRot = 0;
        }
        if(clockwise && rot1<0) {
            if(newRot > 0)
                halfrotated = true;
            if(halfrotated && newRot < 0)
                rotationDone = true;
            if(rotationDone)
                newRot = 0;
        }
        if(!clockwise && rot1<0) {
            if(newRot > 0)
                halfrotated = true;
            if(halfrotated && newRot < 0)
                rotationDone = true;
            if(rotationDone)
                newRot = 0;
        }
        if(!clockwise && rot1>=0) {
            if(newRot < 0)
                halfrotated = true;
            if(halfrotated && newRot > 0)
                rotationDone = true;
            if(rotationDone)
                newRot = 0;
        }

        System.out.println("Rotation Done :: "+rotationDone);

        if(!rotationDone) {
            //BitmapDrawable bitmapDrawable = (BitmapDrawable) dialer.getDrawable();
            //Bitmap bitmap = bitmapDrawable.getBitmap();
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
                    R.drawable.  YOUR_DRBL  );
            int width = bitmap.getWidth();
            int height = bitmap.getHeight();
            Matrix matrix = new Matrix();
            matrix.postRotate(newRot, width, height);
            System.out.println("x===>" + x);
            //System.out.println("y===>" + y);

            //if (x > 250) {
                Bitmap reDrawnBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
                dialer.setImageBitmap(reDrawnBitmap);
            /*} else {
                Bitmap reDrawnBitmap = Bitmap.createBitmap(bitmap, 0, 0,
                        width, height, matrix, true);
                dialer.setImageBitmap(reDrawnBitmap);
            }*/
        }
    }

}
Chintan Raghwani
  • 3,370
  • 4
  • 22
  • 33
  • There r 2 side-effects. 1.]Starting rotation clock-wise from Left hale part OR 2.]Starting rotation anti-clockwise from Right half part. In these both cases, it Rotates image for 1.5 rotations. That is my logic's limitation up to this time. If I will update it, I'll inform u. – Chintan Raghwani Jul 05 '12 at 14:18
  • @Maulik, If you try my demo and get any problem, then inform me by commenting here. – Chintan Raghwani Jul 05 '12 at 14:20