2011-12-23 4 views
0

이것은 실제로 우리의 논문이며, 줄을 단순화 할 때 Ramer-Douglas-Peucker 알고리즘을 사용해야합니다. 안드로이드 앱에서 이것을 구현하는 방법을 알려줄 수 있습니다.안드로이드 : 그려지는 라인에서 포인트 문자열을 얻는 방법?

난 그냥 내가 그려 한 라인에서 점의 문자열을 얻고 총 없음을 줄여 줄을 단순화하는 방법을 알고 싶어요. 포인트는 아래 주어진 코드를 기반으로합니까?

이것은 기본 클래스입니다. 기존 MENU 클릭하면

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에서 라인에 포인트를 생성하는 이유는 단순히 이 생성 된 포인트의 목록을 유지 하시겠습니까? 각 개의 새 선분을 그릴 때 점을 추가 할 수 있습니다. 코드의 관점에서

, 가장 기본적인 예는 다음과 같이 보일 것입니다 :

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 함수를 작성합니다.

직선의 경우 비교적 간단하지만 커브는 난이도를 높입니다. 내부적으로 대부분의 작업을 java.awt.geom.GeneralPath 개체에 위임 한 Path의 소스 코드를 살펴볼 수 있습니다.

+0

네,이 곡선을 포함하므로이 라인의 모든 점을 얻으려면 몇 가지 수학 방정식을 만들거나 적용해야한다는 뜻입니까? – user1081908

+0

글쎄요, 구현하기 가장 쉬운 방법은 아니지만 최선의 선택이라고 생각합니다. 또는 그리기 후에 모든 화면의 픽셀을 반복하여 드로잉하고 드로잉 할 색을 확인함으로써 일종의 '근사'를 수행 할 수 있습니다. 그러나 그리기 순서에 대한 정보는 제공하지 않습니다.라인이 교차하지 않는다면 모든 라인 세그먼트의 시작점과 끝점을 적어도 알고 있기 때문에이 부분을 쉽게 향상시킬 수 있지만 수학을 사용하는 것만 큼 깔끔하지는 않습니다. –

+0

감사합니다. 하지만 정말 시작하기가 어려울 것입니다. 제게 샘플 코드를 제공해 주시겠습니까? 아니면 위의 코드를 확인하십시오. 어떻게 구현합니까? 도와 주셔서 다시 한 번 감사드립니다. – user1081908

관련 문제