2011-09-14 13 views
8

Tengo una imagen de flecha que quiero rotar de 0 a 180 grados (como la aguja en un medidor). Un punto de la flecha se fija en el medio y en la parte inferior de la pantalla y la cabeza de la flecha debe moverse. La longitud de la flecha es fija (es imagen). También tengo dos botones y quiero que la flecha gire a la izquierda cuando se toca el botón izquierdo y gire a la derecha cuando se toca el botón derecho.Android, ¿Cómo puedo rotar una flecha (imagen) alrededor de un punto fijo?

¿Cuál es la lógica de este proceso?

enter image description here

+0

Utilice matrices para aplicar la rotación. –

+1

Duplicado exacto de http://stackoverflow.com/questions/4166917/android-how-to-rotate-a-bitmap-on-a-center-point – Ronnie

+0

te aconsejo al usuario @Emiam answer, esto no usará la CPU como lo hace Matrix. –

Respuesta

2

usted tiene que trabajar con, probablemente, animación utilizando la rotación 3D en Android e intentar también usong matriz de rotación ... Tengo código de mapa de bits para este .........

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 

también puedes ver este

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

+0

Esta no es una buena estrategia porque el método Bitmap.createBitmap es muy lento, y al hacerlo, cada fotograma matará la velocidad de FPS. – Emiam

5

esto es en realidad bastante simple si está utilizando un lienzo para hacer su dibujo (como deberías en tu caso).

Dado que usted conoce las coordenadas para el punto en torno al cual la imagen se debe girar, puede hacerlo de esta manera:

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

grados será un valor entero que aumentar/disminuir cuando el usuario hace clic en el Botones L o R canvas.rotate se ocupa del resto!

+0

Esto realmente no funciona para mí en absoluto (sin rotación, sin salida). Me pregunto si es mi configuración de 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); 

¡Buena suerte!

2

Así que está la respuesta corta y la respuesta larga.

La respuesta corta es que la rotación de bitmaps y lienzos es una función común, generalmente llamada "rotar" y que generalmente toma el punto alrededor del cual girar.

La respuesta más larga es que todos los gráficos en 2D y 3D se convierten en un truco de álgebra matricial. Para cada punto: nueva_matriz_x = factor_1 * + old_x factor_2 * + old_y factor_3 ...

Estos factores funcionan muy bien en una matriz, y es por eso que la cosa matriz se puso tan popular. Hay un buen truco en el que encadenas las transformaciones, por lo que puedes plantear tus problemas como "tomar el lienzo viejo, moverlo para que el punto tocado sea el origen, rotarlo y luego moverlo para que el origen vuelva a estar en cero". el punto tocado ". O Matrix m = new Matrix(). PostTranslate (-touch_x, -touch_y) .postRotate (360/20) .postTranslate (touch_x, touch_y) para rotarlo en 1/20 de círculo cada vez. Luego pasas la matriz a cualquier función que tome la matriz de "transformación".

Lo bueno es que haces todos los cálculos para esa matriz solo una vez, y luego usas las mismas 4 multiplicaciones en cada punto y un montón de suma. De hecho, esto es tan común que las tarjetas de video y el conjunto de instrucciones de Intel hacen ambas cosas en hardware. También puede simplemente multiplicar la imagen resultante nuevamente por la misma matriz para obtener la siguiente.

Ahora, si realmente está pidiendo el truco gráfico de cómo hago esto en un código de ensamblaje increíblemente rápido sin memoria, el truco consiste en recoger rotaciones y errores en pequeñas cadenas donde no necesita un buffer .Por ejemplo, una simple rotación de 90 grados intercambiaría primero las cuatro esquinas, luego cambiaría (arriba a la izquierda + 1 a la izquierda arriba a la derecha + 1 abajo, que va a la esquina inferior derecha - 1 a la izquierda abajo a la izquierda - 1 abajo, vuelve a la esquina superior izquierda + 1). Estos trucos generalmente solo importan para las limitaciones de memoria.

Demasiada información. Cuéntanos más sobre tu problema.

0

VEO this ejemplo, y me he adaptado a trabajar de manera más o menos como lo que necesita, consulte el ejemplo para una mejor comprensión de mi código :)


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

} 

el xml del principal

<?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> 
Cuestiones relacionadas