用手指绘画

4
我发现了这个小例子,可以用手指进行绘制:
http://marakana.com/tutorials/android/2d-graphics-example.html 以下是相关代码:
List<Point> points = new ArrayList<Point>();

@Override
public void onDraw(Canvas canvas) {
    for (Point point : points) {
        canvas.drawCircle(point.x, point.y, 5, paint);
    }
}

public boolean onTouch(View view, MotionEvent event) {
    Point point = new Point();
    point.x = event.getX();
    point.y = event.getY();
    points.add(point);
    invalidate();
    Log.d(TAG, "point: " + point);
    return true;
}

我正在浏览代码,发现他们正将点添加到ArrayList中,然后循环遍历ArrayList。这似乎不是一个非常优化的方法。是否有更好的方法或这是一个好方法?

在我的三星GS3上测试后,我用大小为20的圆涂满了整个屏幕,当颜色越接近完全时,绘制速度越慢,而且圆圈之间的距离也变大了。


你的问题不是很具体,如果你能发布一些代码会更好。 - IluTov
你可能对onDraw教程的期望过高。 - Michael Brewer-Davis
这取决于你想要绘制什么:路径、圆形、正方形等等。 - hardartcore
2个回答

1

首先,使用笔画(而不是圆圈)来画线。其次,进行近似计算。以下是摘要:

  1. Paint更改为使用width=5的笔触。这样可以减少绘制许多圆形的需要。
  2. 选择一个阈值,例如3px,在此之后您将在onTouch()中添加一个点。

    if (Math.abs(previousX - event.getX()) < THRESHOLD
            && Math.abs(previousY - event.getY()) < THRESHOLD) {
        return;
    }
    previousX = event.getX();
    previousY = event.getY();
    // drawing update goes here
    

    这应该会减少(不可察觉的)点数。

  3. 使用PicturePath类来绘制线条,并使用Canvas.drawPath()Canvas.drawPicture()。对于大量的点,这将真正加速绘图,因为所有绘图命令都将在一次调用中传递给内部绘图函数。

  4. 根据需要简化形状。例如,您可以删除最老的点(这将是使用circular buffer的完美案例),使用Ramer-Douglas-Peucker算法,它很容易实现,可以得到良好的结果,并且具有复杂度O(nlogn)


你的阈值示例是否有效?难道不应该是逻辑“与”而不是逻辑“或”吗? - AlanFoster
@AlanFoster 是的,当然你是对的。我已经更新了我的答案中的代码。 - andr

1

不,这个例子中是有意义的。

他循环遍历所有他想要绘制的点。 这意味着他将每个点添加到数组中,以便可以一次性循环遍历所有对象。

在游戏编程中经常会看到这种情况。


这也非常可扩展。

  1. 您可以添加任意数量的要点
  2. 它支持多态性
  3. 您不必为多个要点创建变量 > 代码更少

1
我相信他更关心优化问题。持续向列表中添加点是一个不好的想法。例如,如果点不再可见,则可以将其移除;或者,如果点已经存在于列表中,则可以忽略它。 - AlanFoster
1
@AlanFoster 当然,在将它们添加到数组之前,您必须进行验证检查。否则,您很快就会耗尽内存。 - IluTov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接