2012-07-05 11 views
7

Próbuję obrócić pojedynczy obraz z jego punktu środkowego, ale nie jestem w stanie zatrzymać się w pożądanej pozycji, ponieważ mogę zrobić obrót, ale chcę zatrzymać rotację po 360'(1 round).Zatrzymaj obrót obrazu po stopniu 360 °

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; 
    } 

metoda Obrót @

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); 
     } 
    } 

} 

Twoje sugestie są znaczne.

+0

W jakim kierunku chcesz obrócić? Mam na myśli zgodnie z ruchem wskazówek zegara/przeciwnie do ruchu wskazówek zegara? –

+0

W obu kierunkach iw kierunku przeciwnym do ruchu wskazówek zegara. – Maulik

Odpowiedz

3

Musisz zapisać poprzednią wartość rot. I dodaj metodę updateRotation, jeśli previousRot znajduje się po lewej stronie od 360 stopni, a rot po prawej stronie od 360 stopni, a potem zrobiliśmy 1 rundę i musimy przestać obracać.

Przykładowy kod przypadku zegara

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

W przypadku przeciwnym do wskazówek zegara jest prawie taka sama, ale wartości zamienione

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

Kod ten będzie zatrzymać rotację. Od początku previousRot powinno być 0 dla przypadku ruchu wskazówek zegara i 359.99 dla zegara licznika


Innym podejściem jest dodanie jeszcze jednej zmiennej do przechowywania całkowitą przebytą kąt. Od początku traveledAngle musi być równa 0. A jeśli obracasz się w kierunku zgodnym z ruchem wskazówek zegara, musisz go zwiększyć o różnicę między rot a previousRot. Obracanie w lewo zmniejsza jego wartość o tę samą wartość.

traveledAngle += rot - previousRot; 

Kiedy traveledAngle staje się większa niż 360' trzeba przestać obracać się w kierunku ruchu wskazówek zegara, a kiedy staje się mniej niż 0, trzeba zatrzymać obraca się w kierunku przeciwnym do ruchu wskazówek zegara.

+0

Jak mogę uzyskać kąt większy niż 360 stopni? Będzie to wzrost z 1 'do 360'. po 360 'zajmuje 1 stopień. – Maulik

+0

Zgadza się! Dla kierunku zgodnego z ruchem wskazówek zegara "previousRot" powinno być 350-360 ', a 'rot' powinno być około 0-10'. Ale te liczby podane są tylko na przykład, może to być 300-360 'i 0-60'. Główną ideą jest użycie wartości 'previousRot' – vasart

+0

OK. ale jak mogę zatrzymać rotację za pomocą previousRot? jeśli mam 1 'po jednym obrocie, a moja wartość previousRot wynosi 360'? A jaka powinna być logika w kierunku przeciwnym do ruchu wskazówek zegara? – Maulik

2

Użyłem swoje demo i dodaje pewnej logiki, nowsze demo jest jak poniżej:

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); 
      }*/ 
     } 
    } 

} 
+0

Występują 2 efekty uboczne. 1.] Rozpoczęcie obrotu w kierunku zgodnym z ruchem wskazówek zegara od lewej krawędzi OR LUB 2.] Rozpoczęcie obrotu w lewo od prawej połowy części. W obu tych przypadkach Obraca obraz do 1,5 obrotu.To jest ograniczenie mojej logiki do tego czasu. Jeśli to zaktualizuję, poinformuję cię. –

+0

@Maulik, Jeśli spróbujesz mojego demo i dostaniesz jakiś problem, to poinformuj mnie, komentując tutaj. –