我正在尝试创建一个绘图应用程序,该应用程序将能够沿着屏幕上的触摸路径绘制不同的画笔纹理.
到目前为止,我所做的是:
这是我的自定义视图的代码:
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?中获取了此示例代码
我使用的纹理图像:
我得到什么结果:
我想要达到的结果:
非常感谢您的帮助.
解决方法:
在每个已注册的触摸位置上绘制一个位图是一个不错的开始,但是要创建如您在此处看到的效果那样的平滑效果,您将需要在这里添加更多逻辑.我将概述一些步骤供您实施:
>您将需要更多的位图.一个(或可能几个)位图,它们代表您要绘制的实际线条.如果您有更多内容,效果会更好,因为不是该行的每个部分都看起来一样.然后是线条边缘的另一个位图.
>确保顶点列表是根据收到的输入进行排序的(不确定是否已经这样做).另外,您应该查看列表,并且如果两个相邻点之间的距离小于要绘制的位图的半径,则应忽略该点,因为它不会对您的图形产生太大影响.您可能需要在将点插入列表中时处理此问题,因为这将节省渲染期间的一些计算时间.
>在第一个顶点处,放置一个“边缘”位图,然后根据列表中第一个顶点与第二个顶点之间的角度旋转它.您可以根据Math.atan2(p2.y-p1.y,p2.x-p1.x)知道角度.
>在第一个点之后的每两个点之间,您需要绘制N个位图,N是点i和点i-1之间的距离除以位图的半径.为此,您将需要一个内部循环,该循环运行许多步骤并为每个步骤生成一个新的X / Y坐标.您可以通过从2个点({p2.x-p1.x,p2.y-p1.y},然后进行归一化)创建一个归一化向量,并将其逐步添加到p1中.在每个步骤中,绘制一个位图,然后按照3中的逻辑旋转它.如果内部线的位图超过1个,则随机选择1个.
>在最后一个顶点处,绘制另一个边缘位图,然后根据3中的逻辑再次旋转它.
尽管您可能希望在线条相交的情况下实现更复杂的逻辑,但是这可能会让您入门-在这种情况下,您可能希望拥有(或构造)“相交”位图,并使用更多的逻辑来识别何时发生这种情况以及如何相应地旋转位图.