2012-05-04 19 views
5

Próbuję wyświetlić obraz, który można powiększać i przesuwać, a który obraca się z odczytem kompasu. Z poniższym kodem wszystkie trzy rodzaje działań działają, ale wpływają na siebie nawzajem.Jednoczesne obracanie, tłumaczenie i skalowanie bitmapy w obszarze roboczym z Androidem

Oto co chcę osiągnąć:
1. Obrót wokół środka ekranu
2. Skala pozostawiając taką samą część obrazu w centrum
3. Pan do żądanego miejsca w obrazie

Oto, co faktycznie dzieje się z poniższym kodzie:
1. Rotacja działa zgodnie z przeznaczeniem, po środku ekranu
2. prace skalowanie, ale waga to po środku obrazu
3. Tłumaczenie działa tylko zgodnie z przeznaczeniem, jeśli angle wynosi zero, w przeciwnym razie to zmierza w złym kierunku

// the center of the view port 
float centerX = screen.right/2; 
float centerY = screen.bottom/2; 

Matrix m = new Matrix(); 
m.preRotate(angle, centerX, centerY); 
m.preScale(mScaleFactor, mScaleFactor, centerX, centerY); 

// scaling the amount of translation, 
// rotating the translation here gave crazy results 
float x = mPosX/mScaleFactor; 
float y = mPosY/mScaleFactor; 
m.preTranslate(x, y); 

canvas.drawBitmap(pic, m, null); 

Gdybym przetłumaczyć pierwszy, a później obrócić, tłumaczenie działa zgodnie z przeznaczeniem, ale rotacja nie jest wokół środka port widoku.

Jak zastosować wszystkie trzy transformacje, bez wzajemnego oddziaływania?

Odpowiedz

1

Nie jestem pewien co do skalowania wokół środka obrazu, ale co do tego, że tłumaczenie jest w złym kierunku, czy nie jest to wynikiem obracania obrazu, ale nie tłumaczenia? Może spróbuj coś takiego:

float x = (mPosX*(cos(angle) + sin(angle))/mScaleFactor; 
float y = (mPosY*(cos(angle) - sin(angle))/mScaleFactor; 
m.preTranslate(x, y); 

Również nie przedmiot matryca posiada metodę zastosować affine transformation bezpośrednio? Ponieważ wtedy nie będziesz musiał myśleć o kolejności operacji.

affine transformacja może wyglądać tak:

M = |mScaleFactor*cos(angle)  sin(angle)   x| 
    |  -sin(angle)   mScaleFactor*cos(angle) y| 
    |   0       0    1| 

Ale to będzie się obracać wokół rogu obrazu, więc trzeba użyć preTranslate() function pierwszy tak:

Mt.preTranslate(-centerX,-centerY); 

APLIKUJ Mt do pic przed zastosowaniem M, a następnie po złożeniu wniosku -Mt

+0

Obracanie tłumaczenia wydaje się tylko zrównoważyć rotację, ale mam także wrażenie, że to właśnie to mnie podoba re. Macierze Android to 3x3, więc domyślam się, że już są transformacjami afinicznymi? – modemuser

+0

Może więc spróbuj ustawić macierz bezpośrednio, zamiast korzystać z metod preRotate, preScale? Tak więc twoja macierz powinna być czymś podobnym do edycji w poście powyżej – Dan

+0

Ta macierz działa, przesuwanie działa, ale skalowanie również obraca obraz, obrót także skaluje obraz, a obrót odbywa się wokół rogu obrazu. To jak whac-a-mole, ale dzięki za twój wkład. – modemuser

Powiązane problemy