2013-07-04 5 views
8

Występują problemy podczas korzystania z klasy VelocityTracker. Śledzenie prędkości wydaje się działać bardzo dobrze, jeśli mierzysz prędkość zdarzeń dotykowych w nieprzekraczalnym widoku, ale gdy tylko widok zacznie się poruszać palcem (używając translateY/X lub setY/X), prędkość jest całkowicie losowe (myślę, że prędkość jest obliczana za pomocą pozycji widoku?). Czy ktoś ma jakieś sugestie, aby uzyskać dokładną prędkość ruchu podczas przesuwania widoku?Śledź prędkość ruchomego widoku

Notatki: Używam zdarzeń dotyku z urządzenia onTouchListener w moim widoku do śledzenia prędkości.

Cheers

Odpowiedz

0

Zakładając, że nie są skalowanie, prędkość dotyk jest kwota palec został przeniesiony, podzielona przez czas. Czas jest łatwy do zdobycia - poproś o czas systemowy w milisekundach na każde zdarzenie i podrzędny. W przypadku przetłumaczonego widoku chcesz się upewnić, że używasz tego samego układu odniesienia. Zasadniczo śledź przesunięcie xi y zestawu widoków, tłumacząc je, i dodaj do niego przesunięcie dotyku, aby uzyskać całkowite przesunięcie palca w stosunku do początku. Porównuj tylko te liczby dla swojego śledzenia prędkości.

Jeśli skalujesz widok, staje się on bardziej skomplikowany. Trzeba zrobić ten sam rodzaj matematyki z czynnikiem skalującym. Zasadniczo tłumaczysz wszystkie punkty w tym samym systemie odniesienia.q

+0

OK. To brzmi dość łatwo. Miałem nadzieję, że wykorzystam klasę VelocityTracker i zrobię to dla mnie, ale może sam ją zaimplementuję, tak jak mówisz. –

8

Powinieneś śledzić, jak bardzo widok został przeniesiony i zadzwoń pod numer MotionEvent.offsetLocation, aby "poprawić" współrzędne wydarzenia, zanim przekażesz je do VelocityTracker.

private float mLastX; 
private float mTranslationX; 
private VelocityTracker mTracker; 

@Override 
public boolean onTouch(final View view, MotionEvent motionEvent) { 
    motionEvent.offsetLocation(mTranslationX, 0); 

    switch (motionEvent.getActionMasked()) { 
    case MotionEvent.ACTION_DOWN: 
     mLastX = motionEvent.getRawX(); 
     mTracker = VelocityTracker.obtain(); 
     mTracker.addMovement(motionEvent); 
     return true; 

    case MotionEvent.ACTION_MOVE: 
     mTranslationX += motionEvent.getRawX() - mLastX; 
     view.setTranslationX(mTranslationX); 
     mTracker.addMovement(motionEvent); 
     return true; 

    case MotionEvent.ACTION_UP: 
     // get your correct velocity from mTracker 
     ... 
    } 
} 

sprawdzeniu dokumentacji MotionEvent.getRawX/Y też.

Powodują one przesunięcie współrzędnych X/Y wskaźnika względem całego ekranu, dlatego nie wpływają na ruch tego widoku, którego słuchasz.

-1

Myślę, że mówisz o ruchu kamery, jak podążanie za sportowcem w czasie rzeczywistym. Jeśli tak, to jest tylko jeden sposób: Podczas przechwytywania ruchu potrzebujesz stałego punktu, takiego jak piłka tenisowa w ziemi, aby odjąć prędkość statycznej piłki od "jednego stawu" u sportowca. W tym celu należy uzyskać współrzędne X, Y w początkowej i końcowej klatce obiektu statycznego, aby odróżnić ruch od poruszającego się obiektu.

Ruchomy obiekt: Kwadrat ((X położenie końcowe X pozycja początkowa)^2 + (położenie Y końcowy Y pozycja początkowa)^2) następnie przekształcić pikseli metrów lub mil następnie podzielenie wyniku przez sekundach (również potrzebujesz konwersji z milisekund) otrzymujesz km/h i mp/h dla poruszającego się obiektu.

Wykonaj wszystkie czynności dla obiektu statycznego. Odejmij wynik od statycznego obiektu do poruszającego się obiektu.

To samo dotyczy operacji powiększania. Wszystkie operacje są ręczne. Jeśli chcesz realną prędkość w czasie rzeczywistym, potrzebujesz automatycznego śledzenia nie odpowiedniego dla Androida. W piłce nożnej, używając 4 kamer, potrzebujesz quadprocesorów z minimum 3000Mhz. Radzę użyć Matlaba.

2

Najprostsze promocje sposób z bezwzględnych współrzędnych napisać:

motionEvent.setLocation(e.getRawX(), e.getRawY());

+0

Jeśli spodziewasz się, że MotionEvent będzie używany gdzie indziej, najpierw wykonaj jego kopię, używając MotionEvent.obtain(). –