0

これは実際には私たちの論文です。行を単純化するためにRamer-Douglas-Peuckerアルゴリズムを使用する必要があります。Androidアプリでこれを実装する方法を教えてください。

描いた線から点の文字列を取得し、合計数を減らして線を単純化する方法を知りたいだけです。以下の与えられたコードに基づくポイント?

これがメインクラスです。

public class SketchTimeNewActivity extends GraphicsView implements ColorOption.OnColorChangedListener {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(new MyView(this));

    myPaint = new Paint();
    myPaint.setAntiAlias(true);
    myPaint.setDither(true);
    myPaint.setColor(Color.CYAN);
    myPaint.setStyle(Paint.Style.STROKE);
    myPaint.setStrokeJoin(Paint.Join.ROUND);
    myPaint.setStrokeCap(Paint.Cap.ROUND);
    myPaint.setStrokeWidth(12); 
}

private Paint       myPaint;    

    public void colorChanged(int color) {
    myPaint.setColor(color);
}


public class MyView extends View {

    private static final float MINP = 0.25f;
    private static final float MAXP = 0.75f;

    private Bitmap  mBitmap;
    private Canvas  mCanvas;
    private Path    mPath;
    private Paint   mBitmapPaint;

    public MyView(Context c) {
        super(c);

        mPath = new Path();
        mBitmapPaint = new Paint(Paint.DITHER_FLAG);
    }

    @Override
    protected void onSizeChanged(int width, int height, int oldwidth, int oldheight) {
        super.onSizeChanged(width, height, oldwidth, oldheight);
        mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        mCanvas = new Canvas(mBitmap);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(color.black);

        canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);

        canvas.drawPath(mPath, myPaint);
    }

    private float mX, mY;
    private static final float TOUCH_TOLERANCE = 4;

    private void touch_start(float x, float y) {
        mPath.reset();
        mPath.moveTo(x, y);
        mX = x;
        mY = y;
    }
    private void touch_move(float x, float y) {
        float dx = Math.abs(x - mX);
        float dy = Math.abs(y - mY);
        if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
            mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
            mX = x;
            mY = y;
        }
    }

    private void touch_up() {
        mPath.lineTo(mX, mY);
        // commit the path to our offscreen
        mCanvas.drawPath(mPath, myPaint);
        // kill this so we don't double draw
        mPath.reset();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                touch_start(x, y);
                invalidate();
                break;
            case MotionEvent.ACTION_MOVE:
                touch_move(x, y);
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                touch_up();
                invalidate();
                break;
        }
        return true;
    }
}

private static final int COLOR_MENU_ID = Menu.FIRST;
private static final int EXISTING_MENU_ID = Menu.FIRST + 2;
private static final int ENHANCED_MENU_ID = Menu.FIRST + 3;
private static final int ERASE_MENU_ID = Menu.FIRST + 1;


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);

    menu.add(0, COLOR_MENU_ID, 0, "Color").setShortcut('1', 'c');
    menu.add(0, EXISTING_MENU_ID, 0, "Enhanced").setShortcut('2', 's');
    menu.add(0, ENHANCED_MENU_ID, 0, "Existing").setShortcut('3', 'z');
    menu.add(0, ERASE_MENU_ID, 0, "Erase").setShortcut('4', 'z');

    return true;
}



@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    super.onPrepareOptionsMenu(menu);
    return true;
}



@Override
public boolean onOptionsItemSelected(MenuItem item) {
    myPaint.setXfermode(null);
    myPaint.setAlpha(0xFFAAAAAA);

EXISTING MENUをクリックすると、描画されている線が簡略化され、ポイントの少ない線または既に簡略化された線が表示されます。そのための新しいクラスを作成することを計画していますが、キャンバスに描画されている線からポイントの文字列を取得する方法がわかりません。

    switch (item.getItemId()) {

        case COLOR_MENU_ID:
            new ColorOption(this, this, myPaint.getColor()).show();
            return true;

  /**      case EXISTING_MENU_ID:

            return true;

        case ENHANCED_MENU_ID:

            return true;*/

        case ERASE_MENU_ID:{

                  myPaint.setColor(color.black);
                  myPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
                  return true;
              }

    }

    return super.onOptionsItemSelected(item);
}

}
4

1 に答える 1

0

いくつかのコンテキストについて、元のコメントからコピーして貼り付けます。

onTouchEvent からライン上のポイントを生成しているので、後で Canvas にクエリを実行する代わりに、これらの作成されたポイントのリストを単純に保持してみませんか? 新しい線分を描くたびに点を追加できます。

コードに関しては、最も基本的な例は次のようになります。

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

private void touch_up() {
    // save this point on the line
    mPoints.add(new Point(mX, mY);
    // add point to path
    mPath.lineTo(mX, mY);
    // commit the path to our offscreen
    mCanvas.drawPath(mPath, myPaint);
    // kill this so we don't double draw
    mPath.reset();
}

ここでは、 touch_up() が各線分の始点または終点をパスに追加する場所であると想定しています。

//編集: あなたの問題をもう一度読むと、あなたが描いた線上のすべての点を求めているように感じます-コード スニペットに曲線が含まれているためですか? 私の推測では、これを実現する唯一の方法は、基礎となるさまざまな数式を使用してすべての (x,y) を評価し、各ポイントの結果を保存することです。つまり、独自の lineTo および quadTo 関数を作成することによって。

直線の場合は比較的簡単ですが、曲線の場合は難易度が上がります。Path のソース コードを見てみるとよいでしょう。これは、その作業のほとんどを内部的にjava.awt.geom.GeneralPathオブジェクトに委譲しています。

于 2011-12-23T21:18:56.340 に答える