【Android】贝塞尔曲线原理简介

一、贝塞尔曲线的数学理论

贝赛尔曲线的本质是通过数学计算公式去绘制平滑的曲线。

下面以二阶贝塞尔曲线说明:
在这里插入图片描述

步骤一:在平面内选3个不同线的点并且依次用线段连接。

步骤二:在AB和BC线段上找出点D和点E,使得 AD/AB = BE/BC

步骤三:连接DE,在DE上寻找点F,F点需要满足:DF/DE = AD/AB = BE/BC

步骤四:根据DE线段和计算公式找出所有的F点,然后将其这些点连接起来。

对应的公式为:B(t)=(1-t)2P0+2t(1-t)P1+t2P2,t属于[0,1]

以此类推:三阶贝塞尔曲线如下
在这里插入图片描述

二、android贝塞尔曲线相关方法说明

在Path类中四个方法与贝塞尔曲线相关。

//二阶贝赛尔

public void quadTo(float x1, float y1, float x2, float y2)

参数中(x1,y1)是控制点坐标,(x2,y2)是终点坐标,

贝塞尔曲线的起始点是通过Path.moveTo(x,y)来指定的,而如果我们连续调用quadTo(),前一个quadTo()的终点,就是下一个quadTo()函数的起点;如果初始没有调用Path.moveTo(x,y)来指定起始点,则默认以控件左上角(0,0)为起始点;

一般控制点和终点坐标都是设计定义的,开发中根据设计师给的点推导出起点,终点,控制点。

public void rQuadTo(float dx1, float dy1, float dx2, float dy2)

dx1:控制点X坐标,表示相对上一个终点X坐标的位移坐标,可为负值,正值表示相加,负值表示相减;

dy1:控制点Y坐标,相对上一个终点Y坐标的位移坐标。同样可为负值,正值表示相加,负值表示相减;

dx2:终点X坐标,同样是一个相对坐标,相对上一个终点X坐标的位移值,可为负值,正值表示相加,负值表示相减;

dy2:终点Y坐标,同样是一个相对,相对上一个终点Y坐标的位移值。可为负值,正值表示相加,负值表示相减;

例如:起点为(300,300)控制点为(100,500),终点为(700,300)

path.moveTo(300,300)

Path.quadTo(100,500,700,300)

Path.rQuadTo(100-300,500-300,700-300,300-300)

Path.rQuadTo(-200,200,400,0)

//三阶贝赛尔

3.public void cubicTo(float x1, float y1, float x2, float y2,float x3, float y3)

参数中(x1,y1)是控制点1的坐标,(x2,y2)是控制点2的坐标,(x3,y3)是结束点的坐标。

4.public void rCubicTo(float x1, float y1, float x2, float y2,float x3, float y3)

参数中(x1,y1)是控制点1相对起点的坐标,(x2,y2)是控制点2相对起点的坐标,(x3,y3)是结束点相对起点的坐标。

三、应用

Android中手指轨迹的优化。

优化前,手指轨迹是通过连接移动两点之间的距离组成一条线。对一些拐弯的处理,有明显的连接痕迹。不够平滑。

@Override

    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()){

            case MotionEvent.ACTION_DOWN: {

                mPath.moveTo(event.getX(), event.getY());

                return true;

            }

            case MotionEvent.ACTION_MOVE:

                mPath.lineTo(event.getX(), event.getY());

                postInvalidate();

                break;

            default:

                break;

        }

        return super.onTouchEvent(event);

    }

优化处理,以滑动的AB连线的中间点为贝塞尔起点,B点为控制点,BC连线的中间点为贝塞尔结束点,画一条贝塞尔曲线。

在这里插入图片描述

@Override

    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()){

            case MotionEvent.ACTION_DOWN:{

                mPath.moveTo(event.getX(),event.getY());

                mPreX = event.getX();

                mPreY = event.getY();

                return true;

            }

            case MotionEvent.ACTION_MOVE:{

                float endX = (mPreX+event.getX())/2;

                float endY = (mPreY+event.getY())/2;

                mPath.quadTo(mPreX,mPreY,endX,endY);

                mPreX = event.getX();

                mPreY =event.getY();

                invalidate();

            }

            break;

            default:

                break;

        }

        return super.onTouchEvent(event);

    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值