diff --git a/vtm/src/org/oscim/layers/MapEventLayer.java b/vtm/src/org/oscim/layers/MapEventLayer.java
index 5bd27032..b9d069bc 100644
--- a/vtm/src/org/oscim/layers/MapEventLayer.java
+++ b/vtm/src/org/oscim/layers/MapEventLayer.java
@@ -139,14 +139,17 @@ public class MapEventLayer extends Layer implements InputListener, GestureListen
 			if (mStartMove < 0)
 				return true;
 
+			mTracker.update(e.getX(), e.getY(), e.getTime());
+
 			float vx = mTracker.getVelocityX();
 			float vy = mTracker.getVelocityY();
 
 			/* reduce velocity for short moves */
-			float tx = e.getTime() - mStartMove;
-			if (tx < FLING_THREHSHOLD) {
-				vx *= tx / FLING_THREHSHOLD;
-				vy *= tx / FLING_THREHSHOLD;
+			float t = e.getTime() - mStartMove;
+			if (t < FLING_THREHSHOLD) {
+				t = t / FLING_THREHSHOLD;
+				vy *= t * t;
+				vx *= t * t;
 			}
 			doFling(vx, vy);
 			return true;
@@ -383,8 +386,7 @@ public class MapEventLayer extends Layer implements InputListener, GestureListen
 		int w = Tile.SIZE * 3;
 		int h = Tile.SIZE * 3;
 
-		mMap.animator().animateFling(Math.round(velocityX),
-		                             Math.round(velocityY),
+		mMap.animator().animateFling(velocityX, velocityY,
 		                             -w, w, -h, h);
 		return true;
 	}
@@ -398,105 +400,72 @@ public class MapEventLayer extends Layer implements InputListener, GestureListen
 		return false;
 	}
 
-	/*******************************************************************************
-	 * from libgdx:
-	 * Copyright 2011 Mario Zechner <badlogicgames@gmail.com>
-	 * Copyright 2011 Nathan Sweet <nathan.sweet@gmail.com>
-	 * 
-	 * Licensed under the Apache License, Version 2.0 (the "License");
-	 * you may not use this file except in compliance with the License.
-	 * You may obtain a copy of the License at
-	 * http://www.apache.org/licenses/LICENSE-2.0
-	 * Unless required by applicable law or agreed to in writing, software
-	 * distributed under the License is distributed on an "AS IS" BASIS,
-	 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	 * See the License for the specific language governing permissions and
-	 * limitations under the License.
-	 ******************************************************************************/
-	class VelocityTracker {
-		int sampleSize = 16;
-		float lastX, lastY;
-		float deltaX, deltaY;
-		long lastTime;
-		int numSamples;
-		float[] meanX = new float[sampleSize];
-		float[] meanY = new float[sampleSize];
-		long[] meanTime = new long[sampleSize];
+	static class VelocityTracker {
+		/* sample window, 200ms */
+		private static final int MAX_MS = 200;
+		private static final int SAMPLES = 32;
 
-		public void start(float x, float y, long timeStamp) {
-			lastX = x;
-			lastY = y;
-			deltaX = 0;
-			deltaY = 0;
-			numSamples = 0;
-			for (int i = 0; i < sampleSize; i++) {
-				meanX[i] = 0;
-				meanY[i] = 0;
-				meanTime[i] = 0;
+		private float mLastX, mLastY;
+		private long mLastTime;
+		private int mNumSamples;
+		private int mIndex;
+
+		private float[] mMeanX = new float[SAMPLES];
+		private float[] mMeanY = new float[SAMPLES];
+		private int[] mMeanTime = new int[SAMPLES];
+
+		public void start(float x, float y, long time) {
+			mLastX = x;
+			mLastY = y;
+			mNumSamples = 0;
+			mIndex = SAMPLES;
+			mLastTime = time;
+		}
+
+		public void update(float x, float y, long time) {
+			if (--mIndex < 0)
+				mIndex = SAMPLES - 1;
+
+			mMeanX[mIndex] = x - mLastX;
+			mMeanY[mIndex] = y - mLastY;
+			mMeanTime[mIndex] = (int) (time - mLastTime);
+
+			mLastTime = time;
+			mLastX = x;
+			mLastY = y;
+
+			mNumSamples++;
+		}
+
+		private float getVelocity(float[] move) {
+			mNumSamples = Math.min(SAMPLES, mNumSamples);
+
+			double duration = 0;
+			double amount = 0;
+
+			for (int c = 0; c < mNumSamples; c++) {
+				int index = (mIndex + c) % SAMPLES;
+
+				float d = mMeanTime[index];
+				if (c > 0 && duration + d > MAX_MS)
+					break;
+
+				duration += d;
+				amount += move[index] * (d / duration);
 			}
-			lastTime = timeStamp;
-		}
 
-		public void update(float x, float y, long timeStamp) {
-			long currTime = timeStamp;
-			deltaX = x - lastX;
-			deltaY = y - lastY;
-			lastX = x;
-			lastY = y;
-			long deltaTime = currTime - lastTime;
-			lastTime = currTime;
-			int index = numSamples % sampleSize;
-			meanX[index] = deltaX;
-			meanY[index] = deltaY;
-			meanTime[index] = deltaTime;
-			numSamples++;
-		}
-
-		public float getVelocityX() {
-			float meanX = getAverage(this.meanX, numSamples);
-			float meanTime = getAverage(this.meanTime, numSamples) / 1000.0f;
-			if (meanTime == 0)
+			if (duration == 0)
 				return 0;
-			return meanX / meanTime;
+
+			return (float) ((amount * 1000) / duration);
 		}
 
 		public float getVelocityY() {
-			float meanY = getAverage(this.meanY, numSamples);
-			float meanTime = getAverage(this.meanTime, numSamples) / 1000.0f;
-			if (meanTime == 0)
-				return 0;
-			return meanY / meanTime;
+			return getVelocity(mMeanY);
 		}
 
-		private float getAverage(float[] values, int numSamples) {
-			numSamples = Math.min(sampleSize, numSamples);
-			float sum = 0;
-			for (int i = 0; i < numSamples; i++) {
-				sum += values[i];
-			}
-			return sum / numSamples;
+		public float getVelocityX() {
+			return getVelocity(mMeanX);
 		}
-
-		private long getAverage(long[] values, int numSamples) {
-			numSamples = Math.min(sampleSize, numSamples);
-			long sum = 0;
-			for (int i = 0; i < numSamples; i++) {
-				sum += values[i];
-			}
-			if (numSamples == 0)
-				return 0;
-			return sum / numSamples;
-		}
-
-		//private float getSum (float[] values, int numSamples) {
-		//	numSamples = Math.min(sampleSize, numSamples);
-		//	float sum = 0;
-		//	for (int i = 0; i < numSamples; i++) {
-		//		sum += values[i];
-		//	}
-		//	if (numSamples == 0) return 0;
-		//	return sum;
-		//}
 	}
-
 }
diff --git a/vtm/src/org/oscim/map/Animator.java b/vtm/src/org/oscim/map/Animator.java
index 2dad21f8..541d6f85 100644
--- a/vtm/src/org/oscim/map/Animator.java
+++ b/vtm/src/org/oscim/map/Animator.java
@@ -149,7 +149,7 @@ public class Animator {
 		animStart(duration, ANIM_SCALE);
 	}
 
-	public synchronized void animateFling(int velocityX, int velocityY,
+	public synchronized void animateFling(float velocityX, float velocityY,
 	        int minX, int maxX, int minY, int maxY) {
 
 		if (velocityX * velocityX + velocityY * velocityY < 2048)
@@ -162,8 +162,7 @@ public class Animator {
 
 		float duration = 500;
 
-		// pi times thumb..
-		float flingFactor = (duration / 2500);
+		float flingFactor = 0.5f;
 		mVelocity.x = velocityX * flingFactor;
 		mVelocity.y = velocityY * flingFactor;
 		clamp(mVelocity.x, minX, maxX);