在Android中计算手势距离

时间:2012-09-24 05:00:17

标签: java android

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

3 个答案:

答案 0 :(得分:17)

您可以使用MotionEvent的历史性内容。基于API Doc的示例,您可以执行类似的操作(为简单起见,我的示例不涉及多点触控):

在ACTION_MOVE和ACTION_UP上执行此操作,其中startXstartY将是最后已知的坐标,例如从最后一次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;
}

example image

答案 1 :(得分: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的官方文档,您会看到一个名为批处理的部分,该部分解释了一个给定的动作事件可以将多个移动样本批处理在一起。为了获得最佳的一阶近似,您需要使用所有这些样本 getHistorySizegetHistoricalXgetHistoricalY。不要忘记处理最新的样本,该样本位于getXgetY

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

答案 2 :(得分:0)

我不知道它是否是最佳方式,但您可以在每次MotionEvent.ACTION_MOVE触发数组时捕获数据点,然后计算点到点之间的累积距离。 ......完成手势后指出。