Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/178.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 沿画布上的路径绘制位图_Java_Android_Drawing_Android Canvas - Fatal编程技术网

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

Java 沿画布上的路径绘制位图,java,android,drawing,android-canvas,Java,Android,Drawing,Android Canvas,我正在尝试创建一个绘图应用程序,该应用程序将能够沿屏幕上的触摸路径绘制不同的笔刷纹理。 到目前为止我所做的: 以下是我的自定义视图的代码: public class TestDrawingView extends View{ private Bitmap mBitmapBrush; private Vector2 mBitmapBrushDimensions; private List<Vector2> mPositions = new ArrayList<Vector2&

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

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

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;

}
}
公共类TestDrawingView扩展视图{
私人位图mBitmapBrush;
专用矢量2 MbitMapBushDimensions;
私有列表位置=新的ArrayList(100);
公共TestDrawingView(上下文){
超级(上下文);
//TODO自动生成的构造函数存根
//把刷子放在这里
mBitmapBrush=BitmapFactory.decodeResource(context.getResources(),R.drawable.test\u sand\u brush);
mBitmapBrushDimensions=新矢量2(10,10);
立根基色(0xFFFFFF);
}
@凌驾
受保护的void onDraw(画布){
super.onDraw(帆布);
用于(矢量2位置:位置){
canvas.drawBitmap(mBitmapBrush,pos.x,pos.y,null);
}
}
@凌驾
公共布尔onTouchEvent(运动事件){
int action=event.getAction();
开关(动作){
case MotionEvent.ACTION\u移动:
final float posX=event.getX();
final float posY=event.getY();
add(新向量2(posX-mBitmapBrushDimensions.x/2,posY-mBitmapBrushDimensions.y/2));
使无效();
}
返回true;
}
私有静态最终类向量2{
公共向量2(浮点x,浮点y){
这个.x=x;
这个。y=y;
}
公开最终浮动x;
公开最终浮动;
}
}
我从这个问题中提取了这个示例代码

我使用的纹理图像:

我得到的结果:


我想要达到的结果:


非常感谢您的帮助。

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

  • 你还需要一些比特币。一个(或可能多个)位图,它将表示您试图绘制的实际线条。如果你有更多,效果会更好,因为不是每一段线看起来都一样。然后,为线条的边缘创建另一个位图
  • 确保顶点列表根据收到的输入进行排序(不确定是否已经这样做)。此外,您应该查看列表,如果两个相邻点之间的距离小于正在绘制的位图的半径,则应该忽略该点,因为它不会对您的图形产生太大影响。在将点插入列表时,可能需要处理此问题,因为这样可以在渲染期间节省一些计算时间
  • 在第一个顶点中,放置一个“边”位图,然后根据列表中第一个顶点与第二个顶点之间的角度将其旋转。您可以根据
    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},然后normalize)创建一个规范化向量,并以增量步骤将其添加到p1来实现这一点。在每一步中,绘制一个位图并根据图3中的逻辑旋转它。如果内线有多个位图,则随机选择1
  • 在最后一个顶点处,绘制另一个边位图,并根据3中的逻辑再次旋转它

  • 这应该让您开始了,尽管您可能希望在线自身相交的情况下实现更复杂的逻辑-在这种情况下,您可能希望拥有(或构造)一个“相交”位图,并使用更多的逻辑来确定何时发生这种情况以及如何相应地旋转位图。

    @aoeu()请分享你对此的看法。谢谢你的快速回复,你的回答似乎真的很有帮助。我正在尝试上述所有步骤。你的回答很有帮助。但是,如果您能提供一些更有用的示例代码,这将更有帮助。