Android: Как получить строку точек из нарисованной линии? - PullRequest
0 голосов
/ 23 декабря 2011

Это на самом деле наш тезис, мы должны использовать алгоритм Рамера-Дугласа-Пекера для упрощения линий, любой может помочь мне, как реализовать это в приложении для 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);

При нажатии на СУЩЕСТВУЮЩЕЕ МЕНЮ, это упростит нарисованную линию и покажет линию с меньшимточки или линия, которая уже упрощена.Я планирую создать для него новый класс, но я не знаю, как получить строку точек из линии, нарисованной на холсте.

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

}

1 Ответ

0 голосов
/ 24 декабря 2011

Скопируйте вставку из моего исходного комментария для некоторого контекста:

Вы генерируете точки на линии из вашего 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 () - это место, куда вы добавляете начальную или конечную точку каждого отрезка линии к пути.

// Редактировать: После прочтения вашей проблемы, я чувствую, что вы, возможно, спрашиваете all точки на нарисованной вами линии - поскольку ваш фрагмент кода содержит кривые?Я предполагаю, что единственный способ понять это - оценить каждое (x, y), используя различные базовые математические уравнения, и сохранить результат для каждой точки.Другими словами: написав свои собственные функции lineTo и quadTo.

Для прямых это относительно тривиально, но кривые увеличат уровень сложности.Возможно, вы захотите взглянуть на исходный код Path, который внутренне делегирует большую часть своей работы объекту java.awt.geom.GeneralPath.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...