贝赛尔曲线(二)应用场景之画板优化

转发请注明出处:http://blog.csdn.net/darling_R/article/details/69056376

自定义view之画板很简单,可以看一下下面这个例子。
贝赛尔曲线(二)应用场景之画板优化_第1张图片
简单的画板就是这样的,实现也很简单,主要思路就是,重写OnTouch方法,在按下的时候,记录下来起始点的坐标(tempX,tempY),然后将画笔的路径移动到起点坐标,mPath.moveTo(tempX,tempY);在移动事件下,首先记录下移动后的新坐标 x1,y1;然后调用mPath.lineTo()方法,传入起点和新坐标点的坐标,在这之后,要把新坐标点的值赋给前面的起点坐标,用来当做下一次移动后的起点,这样才能画出连续的线,最后调用invalidate()刷新画布,代码如下:

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawPath(mPath,mPaint);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
   switch (event.getAction()){
     case MotionEvent.ACTION_DOWN:
          tempX = event.getX();
          tempY = event.getY();
          //按下时,将画笔的路径移动到起点
          mPath.moveTo(tempX,tempY);
          break;
     case MotionEvent.ACTION_MOVE:
         //移动过程中产生的新坐标
         float x1 = event.getX();
         float y1 = event.getY();
         //将path移动到新坐标,并连线
         mPath.lineTo(x1,y1);
         //将新坐标赋值给临时变量,目的是将此时的点作为下一次移动后的起点
         tempX = x1;
         tempY = y1;
         //刷新画布,调用onDraw方法
         invalidate();
         break;
     case MotionEvent.ACTION_UP:

          break;
  }
 return true;
}

但是问题来了,仔细观察,不难看出,当快速绘画的时候,线在拐角处的棱角特别明显,不圆滑,原因就是在代码中使用的是 lineTo方法,这个方法就是连接两点的直线,当你快速滑动的时候,两点的距离有点远,所以看到的就是直线。
上篇文章讲到了贝塞尔曲线,知道其原理,那么咱们就可以使用贝塞尔曲线来优化一下,先看一下优化后的效果:
贝赛尔曲线(二)应用场景之画板优化_第2张图片
这个效果相比上一个是不是好很多啊,哈哈,现在来说说他的思路
主要就是运用贝塞尔曲线的原理,既然是两点间的连线,那么我们可以构造出一个控制点来实现贝塞尔曲线,可以取两点之间的中点作为贝塞尔曲线的起始点,然后,移动的点作为控制点,那样的话,绘制出来的曲线就比较圆滑了,可能语言叙述不是很好理解,那么咱么就直接看看代码吧:

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                //每次按下时重置一下画笔路径
                mPath.reset();
                tempX = event.getX();
                tempY = event.getY();
                //按下时,将画笔的路径移动到起点
                mPath.moveTo(tempX, tempY);
                break;
            case MotionEvent.ACTION_MOVE:
                //移动过程中产生的新坐标
                float x1 = event.getX();
                float y1 = event.getY();
                //取两点间的中点作为终点
                float fx = (x1 + tempX) / 2;
                float fy = (y1 + tempY) / 2;
                //使用贝塞尔api
                mPath.quadTo(tempX,tempY,fx,fy);
                //将新坐标赋值给临时变量,目的是将此时的点作为下一次移动后的起点
                tempX = x1;
                tempY = y1;
                //刷新画布
                invalidate();
                break;
            case MotionEvent.ACTION_UP:

                break;
        }
        return true;
    }

相比之前的代码,就多了两行,是不是相对简单易懂一些了。
恩,今天就到这里,该去吃饭了!不明白的,建议去看看医生的视频,讲的不错!

你可能感兴趣的:(贝塞尔曲线-android)