2011-09-14 17 views
8

Mam obraz strzałki, który chcę obrócić od 0 do 180 stopni (jak igła w metrze). Jeden punkt strzałki jest ustalony w środku iu dołu ekranu, a głowa strzałki powinna się poruszać. Długość strzały jest ustalona (to jest obraz). Mam również dwa przyciski i chcę, aby strzałka skręciła w lewo, gdy przycisk zostanie dotknięty i skręci w prawo po dotknięciu prawego przycisku.Android, Jak mogę obrócić strzałkę (obraz) wokół ustalonego punktu?

Jaka jest logika tego procesu?

enter image description here

+0

Użyj macierzy, aby zastosować obrót. –

+1

Dokładny duplikat http://stackoverflow.com/questions/4166917/android-how-to-rotate-a-bitmap-on-a-entercentrum – Ronnie

+0

Polecam użytkownikowi odpowiedź @Emiam, to nie będzie używać procesora tak jak Matrix. –

Odpowiedz

2

Trzeba pracować z użyciem prawdopodobnie animacja 3d obrót w android i starają się również usong macierz obrotu ... Mam kod bitmapy na to .........

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 

również sprawdzić

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

+0

To nie jest dobra strategia, ponieważ metoda Bitmap.createBitmap jest bardzo powolna, a wykonanie tej ramki zabije współczynnik FPS. – Emiam

5

to jest rzeczywiście bardzo proste, jeśli używasz płótno zrobić rysunek (jak powinieneś w twoim przypadku).

Biorąc pod uwagę, że znasz współrzędne punktu, wokół którego obraz powinien obracać, można to zrobić tak:

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

stopni będzie wartość całkowitą, że góra/dół, gdy użytkownik kliknie Przyciski L lub R. canvas.rotate zajmuje się resztą!

+0

To tak naprawdę nie działa dla mnie w ogóle (bez rotacji, bez wyjścia). Zastanawiam się, czy to moja konfiguracja 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); 

Powodzenia!

2

Jest więc krótka odpowiedź i długa odpowiedź.

Krótka odpowiedź brzmi, że obracanie bitmap i płótna jest powszechną funkcją, zwykle nazywaną "obracaniem" i zwykle przyjmuje punkt, w którym ma się obracać.

Dłuższą odpowiedzią jest to, że cała grafika 2D i 3D przekształca się w trik algebry macierzy. Dla każdego punktu: new_x = factor_1 * old_x + factor_2 * old_y + factor_3 ...

czynniki te działają bardzo ładnie w matrycy, i dlatego rzeczą matryca się tak popularne. Jest fajna sztuczka, w której łączysz transformacje ze sobą, więc możesz określić swoje problemy jako "weź stare płótno, przesuń je tak, aby dotknięty punkt był początkiem, obróć go, a następnie przesuń tak, aby pochodzenie powróciło w dotknięty punkt. " Lub Matrix m = new Matrix(). PostTranslate (-touch_x, -touch_y) .postRotate (360/20) .postTranslate (touch_x, touch_y), aby za każdym razem obrócić go o 1/20 okręgu. Następnie przekazujesz macierz do dowolnej funkcji, która przyjmuje matrycę "transformacji".

Fajną rzeczą jest to, że wykonujesz wszystkie obliczenia dla tej macierzy tylko jeden raz, a następnie używasz tych samych 4 multiplikacji w każdym punkcie i pęczku dodawania. W rzeczywistości jest to tak powszechne, że karty graficzne i zestaw instrukcji Intela dokonują tych rzeczy w sprzęcie. Możesz także po prostu pomnożyć wynikowy obraz ponownie za pomocą tej samej matrycy, aby uzyskać następny.

Teraz, jeśli naprawdę pytasz o hackę graficzną tego jak to zrobić w jakimś niesamowicie szybkim kodzie montażowym bez pamięci, to chodzi o wybieranie obrotów i błędów w małe łańcuchy, w których nie potrzebujesz bufora .Na przykład, prosty obrót o 90 stopni zamieniłby najpierw cztery rogi, następnie zamieniłby się (górny lewy + 1 lewy przechodzi w prawy górny + 1 dół, który przechodzi w dolne prawe - 1 lewy, który przechodzi w dolny lewy - 1 dół, który wraca do górnego lewego + 1). Te sztuczki zwykle mają znaczenie tylko dla ograniczeń pamięci.

Zbyt wiele informacji. Powiedz nam więcej o swoim problemie.

0

widzę this przykład i przystosowane do pracy mniej więcej tak jak trzeba, zobacz przykład dla lepszego zrozumienia mojego kodu :)


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

} 

XML głównego

<?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> 
Powiązane problemy