Android贝塞尔曲线——曲线初体验

作者: 邢皓翔 | 来源:发表于2017-01-18 09:10 被阅读0次

    本文来自我的CSDN http://blog.csdn.net/rubeson/article/details/54586828

    今年是2017年,去年最火的一句话就是“给自己定一个小目标,比如先挣他一个亿”。我估计程序员兄弟们也是很有可能去实现这个一个亿的目标的毕竟咱们可以写个程序:

    while(money<一亿){ 
        挣钱....
    }
    

    哈哈,不跟大家开玩笑了,我怕一会被各种扔鞋砸蛋,言归正传今天跟大家分享的是在android中绘制贝塞尔曲线。

    什么是贝塞尔曲线?##

    请看下图


    贝塞尔曲线

    如图所示,贝塞尔曲线画出来的效果就是这样的,其中P0点就是起始点,P1点就是控制点,P2是结束点。所以贝塞尔曲线是由起点、控制点、终点组成的一条曲线。
    当然,一阶的贝塞尔曲线由于是一条直线(只有起始点、终点),所以没有什么研究的价值。我们这次直接从二阶贝塞尔曲线来入手。首先来看一下贝塞尔曲线的绘制过程。


    贝塞尔曲线绘制过程
    通过这个图相信大家一定对贝塞尔曲线的绘制过程有一些了解,他的远离就是通过这个控制点,将起点和终点通过一条平滑的曲线来绘制出来。

    代码中怎样实现##

    那么我们怎样才能绘制出来呢?


    贝塞尔曲线公式

    这个图中的公式就是二阶贝塞尔的公式,那么大家看到公式是不是有种想关掉这个页面的冲动呢? 其实大家大可不必担心,android帮我们封装了贝塞尔曲线api,我们直接去调用就好,这对我们开发来说简直就是一件特别好的事情啊,有木有!! 那我们开始撸码吧。
    首先我们来新建一个java类让它继承View

    public class BezierView extends View {
    // 开始点X,Y坐标
        private float startXPoint;
        private float startYPoint;
    // 结束点X,Y坐标
        private float endXPoint;
        private float endYPoint;
    // 控制点X,Y坐标
        private float conXPoint;
        private float conYPoint;
        private Path mPath;  // 绘制路径
        private Paint mPaint; // 画笔
        
        /**在构造方法中初始化变量*/
        public BezierView(Context context, AttributeSet attrs) {
            super(context, attrs);
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setColor(Color.RED);
            mPaint.setStrokeWidth(8);
        }
     
     /**重写onSizeChanged*/
     @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            // 开始点的坐标
            startXPoint = w / 4;
            startYPoint = h / 2;
            // 结束点的位置
            endXPoint = w * 3 / 4;
            endYPoint = h / 2;
            // 控制点坐标
            conXPoint = w / 2;
            conYPoint = h / 2 - 300;
    
            mPath = new Path();
        }
        
        /**重写onDraw*/
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            mPath.reset(); // 初始化Path
            mPath.moveTo(startXPoint,startYPoint);//移动到开始坐标点开始绘制
            mPath.quadTo(conXPoint,conYPoint,endXPoint,endYPoint); //这段代码就是绘制二阶贝塞尔曲线
            canvas.drawPath(mPath,mPaint);
        }
    }
    

    上面的代码就是我们来绘制二阶的贝塞尔曲线,使用quadTo方法就可以绘制出来一条贝塞尔曲线,然后我们把他引入到我们的布局中去吧,在这里我就省略了布局中的代码了,因为就是简单的引用我们的自定义view。

    那我们来看看效果吧


    贝塞尔曲线效果

    这条线就这么出来了,但是感觉还是有点low,那么我们把他的辅助线也画出来吧,就是类似图一的效果,这些都简单了,直接就是drawLine就可以,那么我们开动吧。我们在刚才程序中加入一些代码

    public class BezierView extends View {
    // 开始点X,Y坐标
        private float startXPoint;
        private float startYPoint;
    // 结束点X,Y坐标
        private float endXPoint;
        private float endYPoint;
    // 控制点X,Y坐标
        private float conXPoint;
        private float conYPoint;
        private Path mPath;  // 绘制路径
        private Paint mPaint; // 画笔
        
        private Paint linePaint; // 用来画辅助线的画笔
        private Paint textPaint; // 用来写字的画笔
        /**在构造方法中初始化变量*/
        public BezierView(Context context, AttributeSet attrs) {
            super(context, attrs);
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setColor(Color.RED);
            
            /**初始化画辅助线的画笔*/
            linePaint= new Paint(Paint.ANTI_ALIAS_FLAG);
            linePaint.setStyle(Paint.Style.STROKE);
            linePaint.setStrokeWidth(3);
            linePaint.setColor(Color.GRAY);
            
            /**初始化写字的画笔*/
            textPaint= new Paint(Paint.ANTI_ALIAS_FLAG);
            textPaint.setStyle(Paint.Style.STROKE);
            textPaint.setTextSize(20);
        }
     
     /**重写onSizeChanged*/
     @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            // 开始点的坐标
            startXPoint = w / 4;
            startYPoint = h / 2;
            // 结束点的位置
            endXPoint = w * 3 / 4;
            endYPoint = h / 2;
            // 控制点坐标
            conXPoint = w / 2;
            conYPoint = h / 2 - 300;
    
            mPath = new Path();
        }
        
        /**重写onDraw*/
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            mPath.reset(); // 初始化Path
            mPath.moveTo(startXPoint,startYPoint);//移动到开始坐标点开始绘制
            mPath.quadTo(conXPoint,conYPoint,endXPoint,endYPoint); //这段代码就是绘制二阶贝塞尔曲线
            
            canvas.drawLine(startXPoint,startYPoint,conXPoint,conYPoint,mPaintCon);
            canvas.drawLine(conXPoint,conYPoint,endXPoint,endYPoint,mPaintCon);
            /**画辅助线*/
            canvas.drawPoint(startXPoint,startYPoint,mPaintCon);
            canvas.drawText("p0",startXPoint - 30,startYPoint,linePaint);
            canvas.drawPoint(endXPoint,endYPoint,linePaint);
            canvas.drawText("p1",endXPoint,endYPoint,textPaint);
            canvas.drawPoint(conXPoint,conYPoint,linePaint);
            canvas.drawText("p2",conXPoint,conYPoint,textPaint);
            
            canvas.drawPath(mPath,mPaint);
        }
    }
    

    至此,我们的曲线已经画完了,请大家看图


    贝塞尔曲线画完辅助线结果图

    我们这个曲线图是不是跟上面的图基本类似了?

    总结##

    经过android封装好的贝塞尔方法是如此的好用,只要找到了开始坐标、控制点坐标、结束坐标就可以轻松的绘制出来。
    当然这个只是一个最基础的二阶贝塞尔,在以后的文章中我还会给大家介绍三阶贝塞尔曲线,喜欢的朋友可以小小关注一下我。你的关注才是我的动力!!!
    遇到什么问题在下方留言,我会第一时间解答的。那么这篇就这样吧,再见~

    相关文章

      网友评论

        本文标题: Android贝塞尔曲线——曲线初体验

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