沿着画布上的路径绘制位图

时间:2014-07-19 11:02:37

标签: java android drawing android-canvas

我正在尝试创建一个绘图应用程序,应用程序将能够沿着屏幕上的触摸路径绘制不同的笔刷纹理。

到目前为止我做了什么:
以下是我的自定义视图的代码:

public class TestDrawingView extends View{

private Bitmap mBitmapBrush;
private Vector2 mBitmapBrushDimensions;

private List<Vector2> mPositions = new ArrayList<Vector2>(100);

public TestDrawingView(Context context) {
    super(context);
    // TODO Auto-generated constructor stub

    // load your brush here
    mBitmapBrush = BitmapFactory.decodeResource(context.getResources(), R.drawable.test_sand_brush);
    mBitmapBrushDimensions = new Vector2(10, 10);

    setBackgroundColor(0xffffffff);

}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    for (Vector2 pos : mPositions) {
        canvas.drawBitmap(mBitmapBrush, pos.x, pos.y, null);
    }
}

@Override
public boolean onTouchEvent(MotionEvent event) {

    int action = event.getAction();
    switch (action) {
    case MotionEvent.ACTION_MOVE:
        final float posX = event.getX();
        final float posY = event.getY();
        mPositions.add(new Vector2(posX - mBitmapBrushDimensions.x / 2, posY - mBitmapBrushDimensions.y / 2));
        invalidate();
    }

    return true;
}

private static final class Vector2 {
    public Vector2(float x, float y) {
        this.x = x;
        this.y = y;
    }

    public final float x;
    public final float y;

}
}

我已从此问题How to make custom brush for canvas in android?

中获取此示例代码

我使用的纹理图像:
enter image description here

我得到了什么结果:
enter image description here


我想要实现的结果:
enter image description here

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:3)

在每个注册的触摸位置上绘制一个位图是一个良好的开端,但为了创建像您在此处看到的那样的平滑效果,您在这里需要更多逻辑。我将概述一些步骤供您实施:

  1. 你需要更多的bitmeps。一个(或可能是几个)位图,代表您尝试绘制的实际线条。如果你有更多,效果会更好,因为不是每一段线看起来都一样。然后是该行边缘的另一个位图。
  2. 确保您的顶点列表根据您收到的输入进行排序(不确定您是否已经这样做了)。此外,您应该遍历列表,如果两个相邻点之间的距离小于您正在绘制的位图的半径,则应忽略该点,因为它不会对其产生很大影响。你的画。您可能希望在将点插入列表时处理此问题,因为它会在渲染过程中节省一些计算时间。
  3. 在第一个顶点,放置一个&#34; edge&#34;位图,然后根据列表中第一个顶点之间的角度将其旋转到第二个。您可以根据Math.atan2(p2.y - p1.y, p2.x - p1.x);
  4. 了解角度
  5. 在第1点之后的每2个点之间,您需要绘制N个位图,N是点i与点i-1之间的距离除以位图的半径。你需要一个内部循环,它运行这么多步骤并为每一步生成一个新的X / Y坐标。您可以通过从2个点({p2.x - p1.x,p2.y - p1.y}创建标准化向量,然后进行标准化)创建标准化向量,然后以递增步骤将其添加到p1。在每个步骤中,绘制一个位图并根据3中的逻辑旋转它。如果内部线有多个位图,则随机选择1。
  6. 在最后一个顶点,绘制另一个边缘位图并根据3中的逻辑再次旋转它。
  7. 这应该可以让你开始,虽然你可能希望在线与自身相交的情况下实现更复杂的逻辑 - 在这种情况下你可能希望拥有(或构建)一个&#34;交叉点&#34;位图并使用更多逻辑来识别何时发生这种情况以及如何相应地旋转位图。