android自定义View基础系列二(贝塞尔曲线)

前言:

好久没写技术博客了。android很多酷炫的自定义VIew效果和贝塞尔曲线相关,像水波纹效、火箭效果等,从本篇开始将研究和使用贝塞尔曲线以及xfermode。相应的效果,以后也会以gif图片展示,更为直观。


概要:

本篇文章主要介绍贝塞尔曲线,以及对于二阶和三阶贝塞尔曲线的简单使用。


正文:

1,什么是贝塞尔曲线

贝塞尔曲线,又称贝兹曲线或者贝济埃曲线,是应用于二位图形应用程序的数学曲线。贝塞尔曲线是由线段和节点组成的,节点是可以拖动的支点,线段像可以伸缩的橡皮筋。是计算机图形学当中比较重要的参数曲线。

这里盗两张图,我们结合常用的一阶贝塞尔曲线、二阶贝塞尔曲线和三阶贝塞尔曲线来理解下:

1)一阶贝塞尔曲线:

          


一阶贝塞尔曲线展现的是一条两点之间的直线。B(t)是t时间下,点的坐标,P0为起点、P1为终点。

t时间点的坐标 B(t)=P0 + (P1 - P0)*t = (1-t)*P0 + P1*t


2)二阶贝塞尔曲线:

   


二阶贝塞尔曲线展现的是一条抛物线。P0至P1之间的连续点Q0,描述一条线段,P1至P2之间的连续点Q1,描述一条线段,Q0至Q1之间的连续点B(t),描述一条二阶贝塞尔曲线。如图Q0视为绿色线段在P0~P1上的点,Q1视为绿色线段在P1~P2上的点。

附上超吃藕手写推算过程害羞



3)三阶贝塞尔曲线:

     

               

具体原理以及推算公式可以参照二阶贝塞尔曲线的推算方式。


贝塞尔曲线通用公式:



说明:P0点到P1点的连续点直线和贝塞尔曲线相切。


2,贝塞尔曲线在android中的相关使用

Android中的Path类提供了绘制贝塞尔曲线的方法。

1)二阶贝塞尔曲线:

       //设置Path移动到起始位置100,300
        mPath.moveTo(100,300);
        //设置辅助点250,300    设置终点400,300
        mPath.quadTo(250,300,400,300);
效果如图:

现在知识一条直线,实现抛物线的效果,我们需要结合onTouch事件,将辅助点的坐标改为动态的:

   @Override
    protected void onDraw(Canvas canvas) {

        mPath.reset();
        mPaint.setColor(Color.parseColor("#ff0000"));
        mPaint.setStrokeWidth(5);
        mPaint.setStyle(Paint.Style.STROKE);

        //设置Path移动到起始位置100,300
        mPath.moveTo(100,300);
        //设置辅助点250,300    设置终点400,300
        mPath.quadTo(supX,supY,400,300);
        canvas.drawPath(mPath,mPaint);
        super.onDraw(canvas);

    }
   @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch(event.getAction()){
            case MotionEvent.ACTION_MOVE:
                supX = event.getX();
                supY = event.getY();
                invalidate();
                break;
            default:
                break;
        }
        return true;
    }
此时的效果:

现在曲线随着辅助点变化,但是辅助点的位置不够直观,没有办法看出辅助点和抛物线的关系,下面把辅助点显示出来。

canvas.drawPoint(supX,supY,mPaint);
现在我们也可以看到辅助点了:


2)三阶贝塞尔曲线:

使用Path类中的cubilTo方法。

cubicTo(float x1, float y1, float x2, float y2,float x3, float y3)
x1,y1是第一个辅助点的坐标;x2,y2是第二个辅助点的坐标;x3,y3是终点的坐标。

直接绘制出效果和辅助点:

   @Override
    protected void onDraw(Canvas canvas) {

        mPath.reset();
        mPaint.setColor(Color.parseColor("#ff0000"));
        mPaint.setStrokeWidth(10);
        mPaint.setStyle(Paint.Style.STROKE);

        //设置Path移动到起始位置100,300
        mPath.moveTo(100,300);
        //设置辅助点250,500  设置辅助点550,150  设置终点800,300
        mPath.cubicTo(250,500,550,150,800,300);
        canvas.drawPath(mPath,mPaint);

        //绘制第一个辅助点
        canvas.drawPoint(250,500,mPaint);
        //绘制第二个辅助点
        canvas.drawPoint(550,150,mPaint);

        super.onDraw(canvas);

    }



关于贝塞尔曲线的使用,实现水波纹等效果,会在下一篇介绍。

猜你喜欢

转载自blog.csdn.net/liujibin1836591303/article/details/58594256