java– 如何在使用可变宽度笔划绘制时使绘制路径平滑

java– 如何在使用可变宽度笔划绘制时使绘制路径平滑,第1张

概述我创建了一个示例绘图应用程序,用户可以使用可变宽度笔划绘制,到目前为止,可变笔划的绘图路径正在工作,但绘制的线条不平滑.我用来实现的代码如下所示.帮助我解决这个问题,因为最近两天我坚持这一点.使用可变笔画宽度绘制路径的代码publicclassFingerPaintextendsGraphicsA

我创建了一个示例绘图应用程序,用户可以使用可变宽度笔划绘制,到目前为止,可变笔划的绘图路径正在工作,但绘制的线条不平滑.我用来实现的代码如下所示.

帮助我解决这个问题,因为最近两天我坚持这一点.

使用可变笔画宽度绘制路径的代码

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 – 如何在使用可变宽度笔划绘制时使绘制路径平滑所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1119065.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-29
下一篇 2022-05-29

发表评论

登录后才能评论

评论列表(0条)

保存