2011-09-14 15 views
8

Ho un'immagine della freccia che voglio ruotare da 0 a 180 gradi (come l'ago in un metro). Un punto della freccia è fissato al centro e nella parte inferiore dello schermo e la testa della freccia dovrebbe muoversi. La lunghezza della freccia è fissa (è l'immagine). Inoltre ho due pulsanti e voglio che la freccia ruoti a sinistra quando il pulsante sinistro viene toccato e gira a destra quando viene toccato il pulsante destro.Android, Come posso ruotare una freccia (immagine) attorno a un punto fisso?

Qual è la logica di questo processo?

enter image description here

+0

Utilizzare le matrici per applicare la rotazione. –

+1

Exact duplicate di http://stackoverflow.com/questions/4166917/android-how-to-rotate-a-bitmap-on-a-center-point – Ronnie

+0

ti consiglio all'utente @Emiam risposta, questo non utilizzerà la CPU come fa Matrix. –

risposta

2

si deve lavorare con probabilmente animazione utilizzando la rotazione 3D in Android e cercare di usong anche matrice di rotazione ... Ho codice bitmap per questo .........

Bitmap bmp=BitmapFactory.decodeResource(getResources(), R.drawable.bar); 
       Matrix mtx = new Matrix(); 
    mtx.postRotate(180); // rotating 180 degrees clockwise 
    Bitmap rotatedBMP = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth() ,bmp.getHeight() , mtx, true); // creating the bitmap image with new angle 

controllare anche questo

http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/animation/Rotate3dAnimation.html

+0

Questa non è una buona strategia perché il metodo Bitmap.createBitmap è molto lento e facendo in modo che ogni fotogramma uccida la frequenza FPS. – Emiam

5

questo è in realtà abbastanza semplice se si utilizza una tela per fare il vostro disegno (come dovresti nel tuo caso).

Dato che si conoscono le coordinate per il punto attorno al quale l'immagine deve ruotare, si può fare in questo modo:

private void doDraw(Canvas canvas) { 
canvas.save(); 
float px = ...; 
float py = ...; 
canvas.rotate(degrees, px, py); 
arrow.draw(canvas); 
canvas.restore(); 
} 

gradi sarà un valore intero che di incremento/decremento quando l'utente fa clic sul L o tasti R. canvas.rotate si prende cura di tutto il resto!

+0

Questo in realtà non funziona per me (nessuna rotazione, nessuna uscita). Mi chiedo se è il mio set-up XML ..? –

1
ImageView arrow = findViewById(/* id of your arrow */); 
int width = arrow.getWidth(); 
int height = arrow.getHeight(); 
newAngle = /* init it by needed angle */; 
RotateAnimation animation = new RotateAnimation(oldAngle, newAngle, width/2, height); 
oldAngle = newAngle; 
animation.setDuration(200); // you may set another duration 
animation.setFillAfter(true); 
arrow.startAnimation(animation); 

Buona fortuna!

2

Quindi c'è la risposta breve e la risposta lunga.

La risposta breve è che la rotazione di bitmap e canvass è una funzione comune, di solito chiamata "rotazione" e di solito prende il punto attorno al quale ruotare.

La risposta più lunga è che tutte le immagini 2D e 3D si trasformano in un trucco di algebra matriciale. Per ogni punto: new_x = factor_1 * old_x + factor_2 * old_y + factor_3 ...

Questi fattori funzionano davvero bene in una matrice, ed è il motivo per cui la cosa matrice ottenuto così popolare. C'è un bel trucco in cui si concatenano le trasformazioni insieme, in modo da poter dichiarare i propri problemi come "prendere la vecchia tela, spostarla in modo che il punto toccato sia l'origine, ruotarla e quindi spostarla in modo che l'origine ritorni a il punto toccato. " Oppure Matrix m = new Matrix(). PostTranslate (-touch_x, -touch_y) .postRotate (360/20) .postTranslate (touch_x, touch_y) per ruotarlo di 1/20 di cerchio ogni volta. Quindi si passa la matrice a qualsiasi funzione che utilizza la matrice di "trasformazione".

La cosa interessante è che si fanno tutti i calcoli per quella matrice solo una volta, e quindi si usano le stesse 4 moltiplicazioni su ogni punto e un mucchio di aggiunte. In effetti, questo è così comune che le schede video e le istruzioni Intel impostano entrambe queste cose nell'hardware. Puoi anche solo moltiplicare l'immagine risultante di nuovo dalla stessa matrice per ottenere quella successiva.

Ora, se si sta davvero chiedendo l'hack grafico di come faccio questo in un codice di assemblaggio follemente veloce senza memoria, il trucco è quello di raccogliere rotazioni ed errori in piccole catene dove non è necessario un buffer .Ad esempio, una semplice rotazione di 90 gradi prima scambierà i quattro angoli, poi cambierebbe (in alto a sinistra + 1 a sinistra va in alto a destra + 1 in basso che va in basso a destra - 1 a sinistra che va in basso a sinistra - 1 in basso, che torna in alto a sinistra + 1). Questi trucchi solitamente interessano solo i vincoli di memoria.

Via troppe informazioni. Dicci di più sul tuo problema.

0

vedo this esempio e mi sono adattato a lavorare più o meno come è necessario, si prega di vedere l'esempio per una migliore comprensione del mio codice :)


import android.app.Activity; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.graphics.Matrix; 
import android.graphics.Paint; 
import android.os.Bundle; 
import android.widget.ImageView; 
import android.widget.SeekBar; 

public class TesteRotateActivity extends Activity implements 
    SeekBar.OnSeekBarChangeListener { 

private ImageView myImageView; 
private SeekBar seekbarRotate; 
private float curScale = 1F; 
private float curRotate = 0F; 
private Bitmap bitmap; 
private int bmpHeight; 

/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    myImageView = (ImageView) findViewById(R.id.imageview); 
    seekbarRotate = (SeekBar) findViewById(R.id.rotate); 
    bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.teste);//here you insert your image 
    bmpHeight = bitmap.getHeight(); 
    drawMatrix(); 
    seekbarRotate.setOnSeekBarChangeListener(this); 
} 

private void drawMatrix() { 
    Matrix matrix = new Matrix(); 
    Matrix matrixb = new Matrix(); 
    Matrix matrixc = new Matrix(); 
    matrix.postScale(curScale, curScale); 
    matrixb.setRotate(curRotate, 100, bmpHeight); 
    matrixc.setTranslate(100, 0); 
    matrix.setConcat(matrixb, matrixc); 
    Bitmap targetBitmap = Bitmap.createBitmap(200, bmpHeight, 
      bitmap.getConfig()); 
    Canvas canvas = new Canvas(targetBitmap); 
    canvas.drawBitmap(bitmap, matrix, new Paint()); 
    myImageView.setImageBitmap(targetBitmap); 
} 

@Override 
public void onProgressChanged(SeekBar seekBar, int progress, 
     boolean fromUser) { 
    curRotate = (float) progress; 
    drawMatrix(); 
} 

@Override 
public void onStartTrackingTouch(SeekBar seekBar) { 
} 

@Override 
public void onStopTrackingTouch(SeekBar seekBar) { 
} 

} 

l'xml di principale

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent" 
android:orientation="vertical" > 

<TextView 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/app_name" /> 

<SeekBar 
    android:id="@+id/rotate" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:layout_margin="5px" 
    android:max="360" 
    android:progress="0" /> 

<ImageView 
    android:id="@+id/imageview" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_gravity="center" 
    android:scaleType="center" /> 

</LinearLayout> 
Problemi correlati