7

我正在尝试找到一种方法来计算手势期间行进的距离。我可以使用 MotionEvent.ACTION_DOWN 和 MotionEvent.ACTION_UP 或 MotionEvent.ACTION_MOVE 获得两点之间的距离。但这并不能说明进入一个圈子。它会计算 0,因为您一直向后移动。我正在寻找总行驶距离,最好以像素为单位,以便在需要时进一步操作它。

4

3 回答 3

22

您可以使用MotionEvent的历史资料。根据 API Doc 的示例,您可以这样做(为简单起见,我的示例不涉及多点触控):

在 ACTION_MOVE 和 ACTION_UP 上执行此操作,其中startX,startY将是最后一个已知坐标,例如来自最后一个 ACTION_DOWN 事件。

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's point
    float dx = (ev.getX(0) - startX);
    float dy = (ev.getY(0) - startY);
    distanceSum += Math.sqrt(dx * dx + dy * dy);
    return distanceSum;
}

示例图像

于 2012-09-24T05:18:21.217 回答
2

一阶近似值是对检测到的每一个微小运动的局部长度求和:

ACTION_DOWN

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

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();

ACTION_UP你可以做任何你想做的事情,total其中​​包含你的路径的总近似长度。

如果您阅读有关MotionEvent http://developer.android.com/reference/android/view/MotionEvent.html的官方文档,您将看到名为Batching的部分,它解释了一个给定的运动事件可以将多个运动样本批处理在一起。为了获得最佳的一阶近似值,您需要使用 getHistorySize, getHistoricalX,来消耗所有这些样本getHistoricalY。不要忘记处理位于getX和中的最新样本getY

如果您需要更好的近似值,我建议您阅读有关曲线拟合问题http://en.wikipedia.org/wiki/Curve_fitting,但由于触摸事件的频率非常快,您可能不需要这样做并获得满足一阶近似。

于 2012-09-24T05:12:24.973 回答
0

我不知道这是否是最好的方法,但是您可以在每次 MotionEvent.ACTION_MOVE 触发到数组时捕获数据点,然后在完成手势后计算从点到点的累积距离……到点。

于 2012-09-24T05:11:37.680 回答