美文网首页
Android自定义View(10) 《贝塞尔曲线简介》

Android自定义View(10) 《贝塞尔曲线简介》

作者: 非典型程序猿 | 来源:发表于2021-09-07 21:33 被阅读0次

    概述

    在Android中的图形绘制中,有个很有名的曲线,叫贝塞尔曲线,可以用来完成一系列非常顺滑的线段动画变化操作,这篇文章就简单学习一下Android自带的贝塞尔曲线的绘制方法。

    贝塞尔曲线绘制原理

    1.一阶贝塞尔曲线

    一阶贝塞尔曲线绘制出来就是一段直线,公式如下


    824232-20170330144601373-1257210437.png

    绘制效果

    824232-20170330142921733-15684048.gif

    2.二阶贝塞尔曲线

    二阶贝塞尔曲线在起点和终点之间多了一个控制点来完成贝塞尔曲线的绘制,公式如下


    824232-20170330144747889-2087843436.png

    绘制效果


    824232-20170330143512014-2132882514.gif

    3.三阶贝塞尔曲线

    三阶贝塞尔曲线则在起点和终点外有两个点来控制贝塞尔曲线的绘制,公式如下


    824232-20170330144819139-1318405514.png

    绘制流程如下


    824232-20170330143748045-500194673.gif

    Android自带绘制贝塞尔曲线的API

    Android的SDK主要有以下两个方法用来绘制贝塞尔曲线

    • 绘制二阶贝塞尔曲线
      rQuadTo()中的参数均为偏移量
    // 二阶贝塞尔曲线
    public void quadTo(float x1, float y1, float x2, float y2)
    public void rQuadTo(float dx1, float dy1, float dx2, float dy2)
    
    • 绘制三阶贝塞尔曲线
      我们一般很少使用三阶的,所以这里只做简单介绍
    // 三阶贝塞尔曲线
    public void cubicTo(float x1, float y1, float x2, float y2, float x3, float y3)
    public void rCubicTo(float x1, float y1, float x2, float y2, float x3, float y3)
    

    简单绘制

    1.绘制一条二阶贝塞尔曲线

    核心代码如下

    override fun onDraw(canvas: Canvas?) {
            super.onDraw(canvas)
            var path = Path()
            path.moveTo(100f,150f)
            path.quadTo(200f,250f,300f,150f)
            path.quadTo(400f,50f,500f,150f)
            canvas?.drawPath(path,paint)
        }
    

    运行结果

    device-2021-09-07-212451.png

    用贝塞尔曲线完成手指滑动路径捕捉

    package com.tx.camera.view
    
    import android.content.Context
    import android.graphics.Canvas
    import android.graphics.Color
    import android.graphics.Paint
    import android.graphics.Path
    import android.util.AttributeSet
    import android.util.Log
    import android.view.MotionEvent
    import android.view.View
    
    /**
     * create by xu.tian
     * @date 2021/9/7
     */
    class BezierView(context: Context?, attrs: AttributeSet?) : View(context, attrs) {
        var paint : Paint = Paint()
        init {
            paint.style = Paint.Style.STROKE
            paint.strokeWidth = 5f
            paint.color = Color.WHITE
        }
    
        var preX = 0f
        var preY = 0f
        var path = Path()
    
        override fun onDraw(canvas: Canvas?) {
            super.onDraw(canvas)
            canvas?.drawPath(path,paint)
        }
    
        override fun onTouchEvent(event: MotionEvent?): Boolean {
            when (event?.action){
                MotionEvent.ACTION_DOWN -> actionDown(event)
           //   MotionEvent.ACTION_MOVE -> linePathMove(event)
                MotionEvent.ACTION_MOVE -> bezierPathMove(event)
            }
            return true
        }
    
        private fun actionDown(event: MotionEvent){
            preX = event.x
            preY = event.y
            path.moveTo(preX,preY)
        }
        // 传统路径捕捉
        private fun linePathMove(event: MotionEvent){
            path.lineTo(event.x,event.y)
            postInvalidate()
        }
        // 利用贝塞尔曲线完成路径捕捉
        private fun bezierPathMove(event: MotionEvent){
            path.quadTo(preX,preY,(event.x+preX)/2,(event.y+preY)/2)
            preX = event.x
            preY = event.y
            postInvalidate()
        }
    }
    

    运行效果


    bezier.gif

    上述例子中将普通的lineTo()方式实现的路径捕捉也写进去了,感兴趣的同学可以对比一下两者的差异,正常情况下贝塞尔实现的会更加顺畅一点。

    总结

    今天就写到这里了,下篇再接着写自定义View的其他内容~

    相关文章

      网友评论

          本文标题:Android自定义View(10) 《贝塞尔曲线简介》

          本文链接:https://www.haomeiwen.com/subject/udgpwltx.html