ジェスチャー中に移動した距離を計算する方法を見つけようとしています。MotionEvent.ACTION_DOWNとMotionEvent.ACTION_UPまたはMotionEvent.ACTION_MOVEを使用して、2点間の距離を取得できます。しかし、それは、たとえば円を描くことを考慮していません。ずっと前に戻ったので、0と計算されます。必要に応じてさらに操作できるように、移動距離の合計を、できればピクセル単位で探しています。
3 に答える
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;
}
一次近似は、検出されたすべての小さな動きの局所的な長さを合計することです。
の上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に関する公式ドキュメントを読むと、1つの特定のモーションイベントが複数の動きのサンプルをまとめてバッチ処理できることを説明する「バッチ処理」というタイトルのセクションが表示されます。getHistorySize
最良の一次近似を行うには、、、getHistoricalX
を使用してこれらすべてのサンプルを消費する必要があります
getHistoricalY
。とにある最新のサンプルを処理することを忘れないでgetX
くださいgetY
。
より良い近似が必要な場合は、カーブフィッティングの問題について読むことをお勧めしますhttp://en.wikipedia.org/wiki/Curve_fittingですが、タッチイベントの頻度が非常に速いため、そうする必要はなく、一次近似に満足。
それが最善の方法かどうかはわかりませんが、MotionEvent.ACTION_MOVEが配列に起動するたびにデータポイントをキャプチャし、ジェスチャの完了時にポイントからポイントへの累積距離を計算できます。