2011-12-23 3 views
0

Это на самом деле наш тезис, мы должны использовать алгоритм Ramer-Douglas-Peucker в упрощающих строках, может ли кто-нибудь помочь мне реализовать это в Android-приложении.Android: Как получить строку точек из линии, нарисованной?

Я просто хочу знать, как получить строку точек из линии я нарисованных и упростить линию за счет снижения общей NO. баллов на основе данного кода ниже?

Это основной класс.

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

} 
+0

Вы генерируете точки на линии из вашего 'onTouchEvent', поэтому вместо того, чтобы пытаться запросить Canvas впоследствии, почему бы просто не сохранить список этих созданных точек? Вы можете добавить точку, когда будете рисовать каждый новый сегмент линии. –

+0

Большое вам спасибо за помощь. Не могли бы вы объяснить, как я это сделаю? Большое вам спасибо, – user1081908

+0

Когда вы говорите, что это ваш тезис, вы имеете в виду, что это домашнее задание? – Zoot

ответ

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.

+0

да это связано с изогнутыми линиями, поэтому это означает, что я должен создать или применить некоторые математические уравнения для получения всех точек в линии? – user1081908

+0

Ну, я бы сказал, это ваш лучший и самый быстрый вариант, хотя, возможно, не самый простой в реализации. В качестве альтернативы вы можете сделать что-то вроде «приближения», итерации по всем пикселям экрана после рисования и проверки цвета, с которым вы рисуете. Это, однако, не даст вам никакой информации о порядке рисования.Если линии не пересекаются, вы можете немного улучшить это, потому что знаете, по крайней мере, знаете начальную и конечную точки каждого сегмента линии, но это будет не так аккуратно, как использование математики. –

+0

Спасибо. но мне очень трудно начать, можете ли вы дать мне пример кода для этого .. или проверить мой код выше, как я его там реализую? Еще раз спасибо за вашу помощь. Я очень ценю это. – user1081908

Смежные вопросы