Calculate gesture distance in Android

I am trying to find a way to calculate the distance traveled during a gesture. I can get the distance between two points using MotionEvent.ACTION_DOWN and MotionEvent.ACTION_UP or MotionEvent.ACTION_MOVE. But this does not mean that you are moving in a circle. It will calculate 0 because you were completely moving. I am looking for the total distance traveled, preferably in pixels, so that I can manipulate it if necessary.

+4
source share
3 answers

You can use the historical MotionEvent material. Using the Doc API example, you can do something like this (for simplicity, my example does not apply to multitouch):

In ACTION_MOVE and ACTION_UP do this where startX , startY will be the last known coordinates, for example. from the last ACTION_DOWN event.

 float getDistance(float startX, float startY, MotionEvent ev) { float distanceSum = 0; final int historySize = ev.getHistorySize(); for (int h = 0; h < historySize; h++) { // historical point float hx = ev.getHistoricalX(0, h); float hy = ev.getHistoricalY(0, h); // distance between startX,startY and historical point float dx = (hx - startX); float dy = (hy - startY); distanceSum += Math.sqrt(dx * dx + dy * dy); // make historical point the start point for next loop iteration startX = hx; startY = hy; } // add distance from last historical point to event point float dx = (ev.getX(0) - startX); float dy = (ev.getY(0) - startY); distanceSum += Math.sqrt(dx * dx + dy * dy); return distanceSum; } 

example image

+12
source

The first first-order approximation would be to sum the local length of each detected tiny element of motion:

On ACTION_DOWN

 total = 0; xPrec = ev.getX(); yPrec = ev.getY(); 

In ACTION_MOVE

 final float dx = ev.getX() - xPrec; final float dy = ev.getY() - yPrec; final float dl = sqrt(dx * dx + dy * dy); total += dl; xPrec = ev.getX(); yPrec = ev.getY(); 

In ACTION_UP you can do whatever you want with total , which contains the total approximate length of your path.

If you read the official MotionEvent documentation MotionEvent http://developer.android.com/reference/android/view/MotionEvent.html , you will see a section called Batching that explains that a given motion event can combine multiple motion patterns. For the best first-order approximation, you need to use all of these patterns using getHistorySize , getHistoricalX , getHistoricalY . Remember to process the last sample, which is in getX and getY .

If you need a better approximation, I suggest you read about the problem of fitting the curve http://en.wikipedia.org/wiki/Curve_fitting , but as the frequency of sensory events is fast enough that you may not need to do this, and be satisfied with the approximation of the first order.

+2
source

I don’t know if this is the best, but you can capture a data point every time MotionEvent.ACTION_MOVE is launched into an array and then calculates the cumulative distance from point to point to point ... indicate a gesture after completion.

0
source

Source: https://habr.com/ru/post/1435835/


All Articles