我创建了一个示例绘图应用程序,用户可以使用可变宽度笔划绘制,到目前为止,可变笔划的绘图路径正在工作,但绘制的线条不平滑.我用来实现的代码如下所示.
帮助我解决这个问题,因为最近两天我坚持这一点.
使用可变笔画宽度绘制路径的代码
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; // for float comparison private static final float stroke_INCREMENT = 0.01f; // amount to interpolate 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(); // Repaints the entire vIEw. 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.reset(); 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 current not roughly equal to target if( Math.abs(targetstroke - currentstroke) > stroke_DELTA ) { // move towards target by the increment 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; } } // Include half the stroke wIDth to avoID clipPing. 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; } } /** * resets the dirty region when the motion event occurs. */ private voID resetDirtyRect(float eventX, float eventY) { // The lasttouchX and lasttouchY were set when the ACTION_DOWN // motion event occurred. dirtyRect.left = Math.min(lasttouchX, eventX); dirtyRect.right = Math.max(lasttouchX, eventX); dirtyRect.top = Math.min(lasttouchY, eventY); dirtyRect.bottom = Math.max(lasttouchY, eventY); } }}
我得到的输出结果
我希望实现的输出
解决方法:
当您检测到更改时,您可以设置目标并插入目标,直到达到它为止,而不是立即跳到新的笔触宽度.你的mstrokes需要是floats而不是Integers.
private static final float stroke_DELTA = 0.0001f; // for float comparisonprivate static final float stroke_INCREMENT = 0.01f; // amount to interpolateprivate float currentstroke = stroke_WIDTH;private float targetstroke = stroke_WIDTH;
您当前为新笔触宽度创建新路径的位置,请执行以下 *** 作:
// if current not roughly equal to targetif( Math.abs(targetstroke - currentstroke) > stroke_DELTA ) { // move towards target by the increment if( targetstroke > currentstroke ) currentstroke = Math.min(targetstroke, currentstroke + stroke_INCREMENT); else currentstroke = Math.max(targetstroke, currentstroke - stroke_INCREMENT); mPath.lineto(mX, mY); mPath = new Path(); mPath.moveto(mX,mY); mPaths.add(mPath); mstrokes.add(currentstroke);}
您将更新当前设置variableWIDthDelta的targetstroke.
总结以上是内存溢出为你收集整理的java – 如何在使用可变宽度笔划绘制时使绘制路径平滑全部内容,希望文章能够帮你解决java – 如何在使用可变宽度笔划绘制时使绘制路径平滑所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)