I created an example drawing application in which the user can draw using the variable width change. So far, the variable stroke drawing path works, but the lines drawn are not smooth. The code I used for this is shown below.
Help me figure out how it has been over the past two days.
Code for drawing a path using a variable stroke width
public class FingerPaint extends GraphicsActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyView(this));
}
public void colorChanged(int color) {
}
public class MyView extends View {
private static final float STROKE_WIDTH = 5f;
private Paint paint = new Paint();
private Path mPath = new Path();
ArrayList<Path> mPaths = new ArrayList<Path>();
ArrayList<Integer> mStrokes = new ArrayList<Integer>();
private float lastTouchX;
private float lastTouchY;
private final RectF dirtyRect = new RectF();
private int lastStroke = -1;
int variableWidthDelta = 0;
private static final float STROKE_DELTA = 0.0001f;
private static final float STROKE_INCREMENT = 0.01f;
private float currentStroke = STROKE_WIDTH;
private float targetStroke = STROKE_WIDTH;
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
public MyView(Context context) {
super(context);
paint.setAntiAlias(true);
paint.setDither(true);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeWidth(STROKE_WIDTH);
}
public void clear() {
mPath.reset();
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
for(int i=0; i<mPaths.size();i++) {
paint.setStrokeWidth(mStrokes.get(i));
canvas.drawPath(mPaths.get(i), paint);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float eventX = event.getX();
float eventY = event.getY();
int historySize = event.getHistorySize();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
resetDirtyRect(eventX, eventY);
mPath.moveTo(eventX, eventY);
mX = eventX;
mY = eventY;
break;
}
case MotionEvent.ACTION_MOVE: {
if (event.getPressure()>=0.00 && event.getPressure()<0.05) {
variableWidthDelta = -2;
} else if (event.getPressure()>=0.05 && event.getPressure()<0.10) {
variableWidthDelta = -2;
} else if (event.getPressure()>=0.10 && event.getPressure()<0.15) {
variableWidthDelta = -2;
} else if (event.getPressure()>=0.15 && event.getPressure()<0.20) {
variableWidthDelta = -2;
} else if (event.getPressure()>=0.20 && event.getPressure()<0.25) {
variableWidthDelta = -2;
} else if (event.getPressure() >= 0.25 && event.getPressure()<0.30) {
variableWidthDelta = 1;
} else if (event.getPressure() >= 0.30 && event.getPressure()<0.35) {
variableWidthDelta = 2;
} else if (event.getPressure() >= 0.35 && event.getPressure()<0.40) {
variableWidthDelta = 3;
} else if (event.getPressure() >= 0.40 && event.getPressure()<0.45) {
variableWidthDelta = 4;
} else if (event.getPressure() >= 0.45 && event.getPressure()<0.60) {
variableWidthDelta = 5;
}
if( Math.abs(targetStroke - currentStroke) > STROKE_DELTA )
{
if( targetStroke > currentStroke)
{
currentStroke = Math.min(targetStroke, currentStroke + STROKE_INCREMENT);
}
else
{
currentStroke = Math.max(targetStroke, currentStroke - STROKE_INCREMENT);
}
}
mStrokes.add((int) currentStroke);
targetStroke = variableWidthDelta;
float dx = Math.abs(eventX - mX);
float dy = Math.abs(eventY - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
if(lastStroke != variableWidthDelta) {
mPath.lineTo(mX, mY);
mPath = new Path();
mPath.moveTo(mX,mY);
mPaths.add(mPath);
}
mPath.quadTo(mX, mY, (eventX + mX)/2, (eventY + mY)/2);
mX = eventX;
mY = eventY;
}
for (int i = 0; i < historySize; i++) {
float historicalX = event.getHistoricalX(i);
float historicalY = event.getHistoricalY(i);
expandDirtyRect(historicalX, historicalY);
}
break;
}
case MotionEvent.ACTION_UP: {
for (int i = 0; i < historySize; i++) {
float historicalX = event.getHistoricalX(i);
float historicalY = event.getHistoricalY(i);
expandDirtyRect(historicalX, historicalY);
}
mPath.lineTo(mX, mY);
break;
}
}
invalidate();
lastTouchX = eventX;
lastTouchY = eventY;
lastStroke = variableWidthDelta;
return true;
}
private void expandDirtyRect(float historicalX, float historicalY) {
if (historicalX < dirtyRect.left) {
dirtyRect.left = historicalX;
} else if (historicalX > dirtyRect.right) {
dirtyRect.right = historicalX;
}
if (historicalY < dirtyRect.top) {
dirtyRect.top = historicalY;
} else if (historicalY > dirtyRect.bottom) {
dirtyRect.bottom = historicalY;
}
}
private void resetDirtyRect(float eventX, float eventY) {
dirtyRect.left = Math.min(lastTouchX, eventX);
dirtyRect.right = Math.max(lastTouchX, eventX);
dirtyRect.top = Math.min(lastTouchY, eventY);
dirtyRect.bottom = Math.max(lastTouchY, eventY);
}
}
}
The result of the output I received

The result that I want to achieve

source
share