Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drawing Bitmap Along a Path on Canvas

I am trying to create a Drawing Application, the Application will be able to draw different Brush Textures along the touched path on the Screen.

What i have done so far:
Here is the code of my Custom View:

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;

}
}

I have taken this example code from this Question How to make custom brush for canvas in android?

The Texture Image that i have used:
enter image description here

What results i am getting :
enter image description here


The Result i want to Achieve :
enter image description here

Any help is highly appreciated.

like image 884
Salman Khakwani Avatar asked Jan 29 '26 18:01

Salman Khakwani


1 Answers

Drawing one bitmap on every registered touch location is a good start, but in order to create a smooth effect like the one you see here, you're going to need a bit more logic here. I'll outline some steps for you to implement:

  1. You'll need a few more bitmeps. One (or possibly several) bitmaps which will represent the actual line you're trying to draw. If you have more, the effect will be better as not every segment of the line will look the same. Then another bitmap for the edges of the line.
  2. Make sure your vertex list is sorted according to the input you received (not sure if you're doing this already or not). Also, you should go over the list, and if the distance between 2 adjacent points is smaller than the radius of the bitmap you're drawing, you should disregard that point as it won't have much of an effect on your drawing. You may want to handle this while you're inserting points into the list as it will save you some computation time during rendering.
  3. In the 1st vertex point, place an "edge" bitmap, then rotate it according to the angle between the 1st vertex in the list, to the second. You can know the angle according to Math.atan2(p2.y - p1.y, p2.x - p1.x);
  4. Between every 2 points after the 1st point, you'll need to draw N bitmaps, N being the distance between point i, and point i-1 divided by the bitmap's radius. You'll need an internal loop for this which runs this many steps and generates a new X/Y coordinate for every step. You can do this by creating a normalized vector from the 2 points ({p2.x - p1.x, p2.y - p1.y}, then normalize), and adding it to p1 in incremental steps. In each step, draw a bitmap and rotate it according to the logic in 3. If you have more than 1 bitmap for the internal line, then select 1 at random.
  5. At the last vertex, draw another edge bitmap and rotate it again according to the logic in 3.

This should get you started, although you may wish to implement more complex logic in cases in which the line intersects itself - in which case you may want to have (or construct) an "intersection" bitmap and use more logic to identify when this happens and how to rotate the bitmap accordingly.

like image 147
Gil Moshayof Avatar answered Jan 31 '26 08:01

Gil Moshayof