/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package com.linkbubble.physics;
import android.view.MotionEvent;
public class FlingTracker {
static final boolean DEBUG = false;
final int MAX_EVENTS = 8;
final float DECAY = 0.75f;
private int mEventBufSize = 0;
private int mEventBufPos = 0;
MotionEventCopy[] mEventBuf = new MotionEventCopy[MAX_EVENTS];
float mVX, mVY = 0;
private static class MotionEventCopy {
public MotionEventCopy(float x2, float y2, long eventTime) {
this.x = x2;
this.y = y2;
this.t = eventTime;
}
public float x, y;
public long t;
}
public FlingTracker() {
for (int i = 0; i < mEventBuf.length; ++i) {
mEventBuf[i] = new MotionEventCopy(0, 0, 0);
}
}
public void addMovement(MotionEvent event) {
if (mEventBufSize == MAX_EVENTS) {
mEventBufPos = (mEventBufPos + 1) % MAX_EVENTS;
} else {
mEventBufSize++;
}
MotionEventCopy me = mEventBuf[(mEventBufSize - 1 + mEventBufPos) % MAX_EVENTS];
me.x = event.getX();
me.y = event.getY();
me.t = event.getEventTime();
}
public void computeCurrentVelocity(long timebase) {
//if (FlingTracker.DEBUG) {
// Slog.v("FlingTracker", "computing velocities for " + mEventBuf.size() + " events");
//}
mVX = mVY = 0;
MotionEventCopy last = null;
int i = 0;
int j = 0;
float totalweight = 0f;
float weight = 10f;
for (int x = 0; x < mEventBufSize; x++) {
MotionEventCopy event = mEventBuf[(MAX_EVENTS + mEventBufSize + mEventBufPos - 1 - x) % MAX_EVENTS];
if (last != null) {
final float dt = (float) (event.t - last.t) / timebase;
if (dt == 0) {
last = event;
continue;
}
final float dx = (event.x - last.x);
final float dy = (event.y - last.y);
//if (FlingTracker.DEBUG) {
// Slog.v("FlingTracker", String.format(" [%d] dx=%.1f dy=%.1f dt=%.0f vx=%.1f vy=%.1f",
// i,
// dx, dy, dt,
// (dx/dt),
// (dy/dt)
// ));
//}
mVX += weight * dx / dt;
mVY += weight * dy / dt;
totalweight += weight;
weight *= DECAY;
j++;
}
last = event;
i++;
}
if (j != 0) {
mVX /= totalweight;
mVY /= totalweight;
}
//if (FlingTracker.DEBUG) {
// Slog.v("FlingTracker", "computed: vx=" + mVX + " vy=" + mVY);
//}
}
public float getXVelocity() {
return mVX;
}
public float getYVelocity() {
return mVY;
}
public void recycle() {
mEventBufSize = 0;
mEventBufPos = 0;
}
static FlingTracker sTracker;
public static FlingTracker obtain() {
if (sTracker == null) {
sTracker = new FlingTracker();
}
return sTracker;
}
}