贝塞尔曲线

                                                                                                              贝塞尔曲线

什么是贝塞尔曲线

贝塞尔曲线(Bézier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线。一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段节点组成,节点是可拖动的支点,线段像可伸缩的皮筋,我们在绘图工具上看到的钢笔工具就是来做这种矢量曲线的。主要结构:起始点、终止点(也称锚点)、控制点。通过调整控制点,贝塞尔曲线的形状会发生变化。


贝塞尔曲线的分类

了解一下贝塞尔曲线,根据影响变量的个数不同,我们可以看到不同类型的曲线


一阶贝塞尔曲线(线段):

公式: 



意义:由 P0 至 P1 的连续点, 描述的一条线段


二阶贝塞尔曲线(抛物线)

公式: 




原理: 由 P0 至 P1 的连续点 Q0,描述一条线段。 
           由 P1 至 P2 的连续点 Q1,描述一条线段。 
           由 Q0 至 Q1 的连续点 B(t),描述一条二次贝塞尔曲线。


三阶贝塞尔曲线:




当然还有四阶曲线、五阶曲线......只不过随着变量的增加,复杂维度会越来越高


虽然从公式上理解是非常难得,我们在开发中,也不是必须要完全理解这些公式,大概知道原理即可,通过这篇文章,我们可以大概理解它的图形上面的变化实现 http://www.html-js.com/article/1628

这个工具网站,可以帮助我们去绘制贝塞尔曲线 http://bezier.method.ac/#


贝塞尔曲线代码实现:

用自定义view实现:

public class BezierClass extends View {

    private Paint mPaint;

    private Path mPath;


    private Paint paint;


    private int viewWidth, viewHeight;
    //控件的宽和高

    private float commandX, commandY;
    //控制点的坐标

    private float waterHeight;
    //水位高度


    private boolean isInc;
// 判断控制点是该右移还是左移


    @Override

    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        viewWidth = w;

        viewHeight = h;

        commandY = 7 / 8f * viewHeight;

        //红色辅助线

        waterHeight = 15 / 16f * viewHeight;

    }


    @Override

    protected void onDraw(Canvas canvas) {

        super.onDraw(canvas);

        //起始点位置

        mPath.moveTo(-1/4f*viewWidth,waterHeight);

        //水波浪

        mPath.quadTo(commandX,commandY,viewWidth+1/4f*viewWidth,waterHeight);

        //水波浪下方闭合区域

        mPath.lineTo(viewWidth+1/4f*viewWidth,viewHeight);

        mPath.lineTo(-1 / 4F * viewWidth, viewHeight);

        mPath.close();

        //绘制路径

        canvas.drawPath(mPath, mPaint);

        //绘制红色水位高度辅助线

        canvas.drawLine(0,waterHeight,viewWidth,waterHeight,paint);

        //产生波浪左右涌动的感觉

        if (commandX >= viewWidth + 1 / 4F * viewWidth) {
//控制点坐标大于等于终点坐标改标识

            isInc = false;

        } else if (commandX <= -1 / 4F * viewWidth)
        {
//控制点坐标小于等于起点坐标改标识

            isInc = true;

        }

        commandX = isInc ? commandX + 20 : commandX - 20;

        //水位不断加高  当距离控件顶端还有1/8的高度时,不再上升

        if (commandY >= 1 / 8f * viewHeight) {

            commandY -= 2;

            waterHeight -= 2;

        }

        //路径重置

        mPath.reset();

        // 重绘

        invalidate();

    }

    /**

     * 测量

     */

    @Override

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

//        int wSpecMode = MeasureSpec.getMode(widthMeasureSpec);

//        int wSpecSize = MeasureSpec.getSize(widthMeasureSpec);

//        int hSpecMode = MeasureSpec.getMode(heightMeasureSpec);

//        int hSpecSize = MeasureSpec.getSize(heightMeasureSpec);
//
//        if (wSpecMode == MeasureSpec.AT_MOST && hSpecMode == MeasureSpec.AT_MOST) {

//            setMeasuredDimension(300, 300);

//        } else if (wSpecMode == MeasureSpec.AT_MOST) {
//            setMeasuredDimension(300, hSpecSize);
//
  //  } else if (hSpecMode == MeasureSpec.AT_MOST) {

//            setMeasuredDimension(wSpecSize, 300);
//        }
    }

    public BezierClass(Context context) {

        super(context);

        init();


    }

    public BezierClass(Context context, @Nullable AttributeSet attrs) {

        super(context, attrs);

        init();

    }


    public BezierClass(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        init();

    }


    /**
     * 初始化画笔 路径

     */
    private void init() {

        //画笔

        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

        mPaint.setColor(Color.parseColor("#AFDEE4"));

        //路径
        mPath = new Path();

        //辅助画笔

        paint = new Paint(Paint.ANTI_ALIAS_FLAG);

        paint.setColor(Color.RED);
        paint.setStrokeWidth(5f);

    }

}
在mainxml文件布局:

<test.bwei.com.beisaier.BezierClass
    android:id="@+id/bc"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

mainActivity主方法:   《主方法没有逻辑》
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值