4

指で描画するためのこの小さなサンプル コードを見つけました:
http://marakana.com/tutorials/android/2d-graphics-example.html

関連するコードの一部を次に示します。

List<Point> points = new ArrayList<Point>();

@Override
public void onDraw(Canvas canvas) {
    for (Point point : points) {
        canvas.drawCircle(point.x, point.y, 5, paint);
    }
}

public boolean onTouch(View view, MotionEvent event) {
    Point point = new Point();
    point.x = event.getX();
    point.y = event.getY();
    points.add(point);
    invalidate();
    Log.d(TAG, "point: " + point);
    return true;
}

私はそれを調べていて、ArrayListにポイントを追加し、ArrayListをループしていることを見ました。これは、これに対する非常に最適化されたアプローチではないようです。より良いアプローチはありますか、それともこれは良いアプローチですか?

私の Samsung GS3 でテストした後、画面全体を円のサイズ 20 で色付けしました。フルカラーに近づくほど、描画に時間がかかり、円の間隔が空いていきました。

4

2 に答える 2

1

いいえ、これはこの例では理にかなっています。

彼は、描画したいすべてのポイントをループします。これは、すべてのポイントを配列に追加することを意味するため、すべてのオブジェクトを一度にループできます。

これは、ゲーム プログラミングでよく見られます。


これも非常に拡張性があります。

  1. 好きなだけポイントを追加できます
  2. ポリモーフィズムをサポート
  3. 複数のポイントの変数を作成する必要はありません >少ないコード
于 2012-12-23T01:10:37.613 に答える
1

まず、ストローク (円ではなく) を使用して線を描画します。第二に、概算。要約は次のとおりです。

  1. Paintでストロークを使用するように変更しますwidth=5。これにより、非常に多くの円を描く必要がなくなります。
  2. しきい値を選択します。たとえば3px、その後にポイントを追加しますonTouch()

    if (Math.abs(previousX - event.getX()) < THRESHOLD
            && Math.abs(previousY - event.getY()) < THRESHOLD) {
        return;
    }
    previousX = event.getX();
    previousY = event.getY();
    // drawing update goes here
    

    これにより、(目立たない) ポイントの数が減るはずです。

  3. Pictureまたはクラスを使用Pathして線を描画し、Canvas.drawPath()またはを使用しますCanvas.drawPicture()。すべての描画コマンドが 1 回の呼び出しで内部描画関数に渡されるため、これは、特に多数の点の場合、描画を本当に高速化します。

  4. 必要に応じて形状を単純化します。たとえば、最も古いポイントを削除し (循環バッファーを使用するのに最適なケースです)、Ramer-Douglas-Peucker アルゴリズムを使用できます。これは実装が非常に簡単で、良い結果が得られ、複雑さがO(nlogn).

于 2012-12-23T06:17:45.867 に答える