2013-07-04 9 views
8

Sto riscontrando problemi durante l'utilizzo della classe VelocityTracker. Il tracciamento della velocità sembra funzionare molto bene se stai misurando la velocità degli eventi tattili su una vista non in movimento, ma non appena la vista inizia a muoversi con il dito (usando usando translateY/X o setY/X), la velocità è completamente casuale (penso che la velocità sia calcolata usando la posizione della vista?). Qualcuno ha qualche suggerimento per ottenere una velocità precisa del movimento quando si scorre una vista?Traccia la velocità di una vista in movimento

Note: Sto utilizzando gli eventi di tocco da onTouchListener di my View per il tracciamento Velocity.

Acclamazioni

risposta

0

supponendo che non sono in scala, la velocità di un tocco è la quantità il dito è mosso, diviso per il tempo. Il tempo è facile da ottenere: basta richiedere l'ora di sistema in millisecondi per ogni evento e sottottrollo. Per una vista tradotta, devi assicurarti di utilizzare lo stesso fotogramma di riferimento. In pratica, tieni traccia dell'offset xey della vista impostata traducendolo e aggiungi l'offset del tocco su di esso per ottenere l'offset totale del dito rispetto all'origine. Confronta solo quei numeri per il tuo tracciamento della velocità.

Se si ridimensiona la vista, diventa più complicato. Devi fare lo stesso tipo di matematica con il fattore di scala. Fondamentalmente stai traducendo tutti i punti nello stesso sistema di riferimento.

+0

OK. Sembra abbastanza facile. Speravo di usare la classe VelocityTracker e averlo fatto per me, ma forse lo implementerò da solo come dici tu. –

8

È necessario tenere traccia di quanto è stata spostata la vista e chiamare MotionEvent.offsetLocation per "correggere" le coordinate dell'evento prima di passarlo a 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 
     ... 
    } 
} 

Controllare la documentazione per MotionEvent.getRawX/Y troppo.

Restituiscono le coordinate X/Y del puntatore relative all'intero schermo, pertanto non sono influenzate dal movimento di qualsiasi Vista in ascolto.

-1

Penso che tu stia parlando del movimento della telecamera, come seguire un atleta in tempo reale. Se è così, c'è solo un modo: durante la cattura del movimento hai bisogno di un punto fisso, come una pallina da tennis nel terreno per sottrarre la velocità della palla statica a "una canna" nell'atleta. Per fare ciò è necessario ottenere le coordinate X, Y nel fotogramma iniziale e finale dell'oggetto statico per fare la differenza con l'oggetto in movimento.

Moving object: Square ((X posizione finale-X posizione iniziale)^2 + (posizione Y-Y finale posizione iniziale)^2) poi convertire pixel a metri o miglia quindi dividere il risultato per secondi (anche hai bisogno di una conversione da millisecondi) ottieni km/he mp/h per l'oggetto in movimento.

Eseguire tutti i passaggi per l'oggetto statico. Sottrai il risultato dall'oggetto statico all'oggetto in movimento.

Lo stesso vale per le operazioni di zoom. Tutte le operazioni sono manuali. Se si desidera la velocità reale in tempo reale è necessario il tracciamento automatico non adatto per Android. Nel calcio, usando 4 telecamere hai bisogno di quadriprocessore con minimo 3000Mhz. Consiglio di usare Matlab.

2

I più semplici offerte vie con coordinate assolute scrivere:

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

+0

Se si prevede che MotionEvent venga utilizzato altrove, crearne prima una copia usando MotionEvent.obtain(). –

Problemi correlati