Home » Android » android – Track the velocity of a moving view

android – Track the velocity of a moving view

Posted by: admin June 15, 2020 Leave a comment

Questions:

I’m running into issues when using the VelocityTracker class. Velocity tracking seems to work very well if you are measuring the velocity of touch events on a non-moving view, but as soon as the view starts moving with your finger (using using translateY/X or setY/X), the velocity is completely random (I think the velocity is calculated using the view’s position?). Does anyone have any suggestions for getting an accurate velocity of your movement when swiping a view?

Notes:
I am using the touch events from my View’s onTouchListener for Velocity tracking.

Cheers

How to&Answers:

You should keep track of how much the view has been moved and call MotionEvent.offsetLocation to “fix” the event coordinates before passing it to 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
      ...
  }
}

Check out the documentation for MotionEvent.getRawX / Y too.

They return the X/Y coordinates of the pointer relative to the entire screen, therefore they aren’t affected by the movement of whatever View you’re listening on.

Answer:

The simplest way deals with absolute coordinates write:

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

Answer:

Assuming you aren’t scaling, the velocity of a touch is the amount your finger has moved, divided by the time. Time is easy to get- just request the system time in milliseconds on each event and subtrace. For a translated view, you want to make sure that you use the same frame of reference. Basically keep track of the x and y offset of the view set by translating it, and add the offset of the touch to it to get the total offset of your finger relative to origin. Only compare those numbers for your velocity tracking.

If you’re scaling the view as well, it gets more complicated. You need to do the same kind of math with the scaling factor. Basically you’re translating all points into the same reference system.q

Answer:

I think you are talking about the camera movement, like following an athlete in real time.
If so, there is only one way: During the capture of the movement you need a fixed point, like a tennis ball in the ground to subtract the velocity of the static ball to “one joint” in the athlete.
To do this is necessary to obtain the X, Y coordinates in the initial and final frame of the static object to make the difference to the moving object.

Moving object: Square((X position final-X position initial)^2 + (Y position final-Y position initial)^2 )
then convert pixels to meters or miles
then divide the result by seconds (also need a convertion from miliseconds)
you get km/h and mp/h for the moving object.

Do all steps for the static object.
Subtract the result from the static object to the moving object.

The same applies to zoom operations.
All the operations are manual. If you want the real velocity in real time you need automatic tracking not suitable for android. In soccer, using 4 cameras you need quadprocessors with minimum 3000Mhz. I advice to use Matlab.