【问题标题】:Android: How to get the string of points from the line being drawn?Android:如何从正在绘制的线中获取点串?
【发布时间】:2012-01-26 15:38:29
【问题描述】:

这实际上是我们的论文,我们需要使用 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);

单击现有菜单时,它将简化正在绘制的线并显示具有较少点的线或已简化的线。我打算为它创建一个新类,但我不知道如何从画布中绘制的线中获取点串。

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

}

【问题讨论】:

  • 您正在从您的onTouchEvent 生成线上的点,所以与其在之后尝试查询画布,为什么不简单地保留这些创建点的列表?您可以在绘制每个新线段时添加一个点。
  • 非常感谢您的帮助。你能进一步解释我将如何做吗?非常感谢,
  • 当你说这是你的论文时,你的意思是这是作业吗?
  • 是的。也许你能帮助我,非常感谢

标签: java android douglas-peucker


【解决方案1】:

从我的原始评论中复制粘贴以获取某些上下文:

您正在从 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() 是您将每个线段的起点或终点添加到路径的位置。

//编辑:再次阅读您的问题后,我觉得您可能会要求您绘制的直线上的所有点 - 因为您的代码 sn-p 包含曲线?我的猜测是,实现这一点的唯一方法是使用不同的基础数学方程评估每个 (x,y) 并存储每个点的结果。换句话说:通过编写自己的 lineTo 和 quadTo 函数。

对于直线,这相对微不足道,但曲线会增加难度。您可能想查看 Path 的源代码,它在内部将大部分工作委托给 java.awt.geom.GeneralPath 对象。

【讨论】:

  • 是的,这涉及曲线,所以这意味着我必须创建或应用一些数学方程来获取线上的所有点?
  • 好吧,我会说这是您最好和最快的选择,虽然可能不是最容易实现的。或者,您可以通过在绘制后遍历所有屏幕像素并检查您绘制的颜色来潜在地进行某种“近似”。但是,这不会为您提供有关绘图顺序的任何信息。如果线条没有交叉,您可以轻松地增强一下,因为您至少知道每个线段的起点和终点,但它不会像使用数学那样整洁。
  • 谢谢。但我真的觉得很难开始,你能给我一个示例代码吗?或者检查我上面的代码,我将如何在那里实现它?再次感谢您的帮助,我非常感谢。
  • 获取线性线或曲线上每个点的 (x,y) 坐标的关键是具有数学表示(公式)。线的那些是高中数学,而二次贝塞尔曲线的细节很普遍 - 例如。 Wikipedia 为通用公式。您还可以使用许多示例实现作为起点 - 您甚至可以出于您的目的主要复制粘贴/修改 Java 的内置 QuadCurve2D 类(尽管它在 Android 中缺失)。
  • 我已经为 QuadCurve2D 类找到了一些代码 sn-ps,我仍在尝试分析它。我也在寻找 Java 中的 Douglas-Peucker 实现。你知道我在哪里可以找到一个好的吗?再次感谢您
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-13
  • 2011-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多