android:贝塞尔曲线简单实现

来源:互联网 发布:网络卖电影挣钱 编辑:程序博客网 时间:2024/05/16 14:42

原理图:
这里写图片描述

看了半天网上的讲解,我也不是很懂,上面的公式 ,大概让我知道了些,原来这平滑的曲线,是用这公式得出的。不研究里面具体的算法了,下面说下在安卓上怎么实现。感谢http://weibo.com/GcsSloop?is_hot=1,我从这里获取的资料。

1.二阶贝塞尔曲线绘制
谷歌封装了一个方法quadTo,给出起点,控制点以及终点,就可以直接绘制二阶贝塞尔取消,demo如下

package com.wx.beziermaker;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.graphics.PointF;import android.view.MotionEvent;import android.view.View;/** * Created by huqing on 2016/6/27. */public class TwoBezier extends View {    private Paint mPaint;    private int centerX, centerY;    private PointF start, end, fingerPoint;    /**     *     使用,例:     *    TwoBezier mBezier = new TwoBezier(this);     *    setContentView(mBezier);     *     * @param context     */    public TwoBezier(Context context) {        super(context);        //画笔        mPaint = new Paint();        mPaint.setStrokeWidth(8);        mPaint.setStyle(Paint.Style.STROKE);        mPaint.setTextSize(60);        //三点确定该二阶曲线        start = new PointF(0, 0);        end = new PointF(0, 0);        fingerPoint = new PointF(0, 0);    }    /**     * 手指触碰时获取当前手指坐标     * @param event     * @return     */    @Override    public boolean onTouchEvent(MotionEvent event) {        // 根据触摸位置更新控制点,并提示重绘        fingerPoint.x = event.getX();        fingerPoint.y = event.getY();        invalidate();//调用onDraw方法        return true;    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        // 绘制数据点和控制点        mPaint.setColor(Color.GRAY);        mPaint.setStrokeWidth(20);        canvas.drawPoint(start.x, start.y, mPaint);        canvas.drawPoint(end.x, end.y, mPaint);        canvas.drawPoint(fingerPoint.x, fingerPoint.y, mPaint);        // 绘制辅助线        mPaint.setStrokeWidth(4);        canvas.drawLine(start.x, start.y, fingerPoint.x, fingerPoint.y, mPaint);        canvas.drawLine(end.x, end.y, fingerPoint.x, fingerPoint.y, mPaint);        // 绘制贝塞尔曲线        mPaint.setColor(Color.RED);        mPaint.setStrokeWidth(8);        //绘制曲线路径        Path path = new Path();        //起点        path.moveTo(start.x, start.y);        //关键方法:谷歌封装好的贝塞尔曲线绘制方法quadTo,给出控制点和终点        path.quadTo(fingerPoint.x, fingerPoint.y, end.x, end.y);        canvas.drawPath(path, mPaint);    }    /**     * onSizeChanged的启动时间在onDraw之前,初始化该View时获取到长宽     */    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        //中心点        centerX = w / 2;        centerY = h / 2;        //左侧点        start.x = centerX - 200;        start.y = centerY;        //右侧点        end.x = centerX + 200;        end.y = centerY;        //控制点,就是手指移动的那个点        fingerPoint.x = centerX;        fingerPoint.y = centerY - 100;    }}

2.三阶贝塞尔曲线绘制
谷歌封装了一个方法cubicTo,给出起点,控制点以及终点,就可以直接绘制三阶贝塞尔取消,demo如下

import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.graphics.PointF;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;/** * Created by huqing on 2016/6/27. */public class BezierThree extends View {    private Paint mPaint;    private int centerX, centerY;    private PointF start, end, fingerPointOne, fingerPointTwo;    private boolean mode = true;    public BezierThree(Context context) {        this(context, null);    }    public BezierThree(Context context, AttributeSet attrs) {        super(context, attrs);        //画笔        mPaint = new Paint();        mPaint.setColor(Color.BLACK);        mPaint.setStrokeWidth(8);        mPaint.setStyle(Paint.Style.STROKE);        mPaint.setTextSize(60);        //中间点        start = new PointF(0, 0);        end = new PointF(0, 0);        fingerPointOne = new PointF(0, 0);        fingerPointTwo = new PointF(0, 0);    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        centerX = w / 2;        centerY = h / 2;        // 初始化数据点和控制点的位置        start.x = 10;        start.y = centerY;        end.x = w - 10;        end.y = centerY;        fingerPointOne.x = centerX;        fingerPointOne.y = centerY - 100;        fingerPointTwo.x = centerX;        fingerPointTwo.y = centerY - 100;    }    @Override    public boolean onTouchEvent(MotionEvent event) {    // 根据触摸位置更新控制点,并提示重绘        if (mode) {            fingerPointOne.x = event.getX();            fingerPointOne.y = event.getY();        } else {            fingerPointTwo.x = event.getX();            fingerPointTwo.y = event.getY();        }        invalidate();        return true;    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);//        以下是辅助理解的线条和点//        // 绘制数据点和控制点//        mPaint.setColor(Color.GRAY);//        mPaint.setStrokeWidth(20);//        canvas.drawPoint(start.x, start.y, mPaint);//        canvas.drawPoint(end.x, end.y, mPaint);//        canvas.drawPoint(fingerPointOne.x, fingerPointOne.y, mPaint);//        canvas.drawPoint(fingerPointTwo.x, fingerPointTwo.y, mPaint);//        // 绘制辅助线//        mPaint.setStrokeWidth(4);//        canvas.drawLine(start.x, start.y, fingerPointOne.x, fingerPointOne.y, mPaint);//        canvas.drawLine(fingerPointOne.x, fingerPointOne.y, fingerPointTwo.x, fingerPointTwo.y, mPaint);//        canvas.drawLine(fingerPointTwo.x, fingerPointTwo.y, end.x, end.y, mPaint);        // 绘制贝塞尔曲线        mPaint.setColor(Color.RED);        mPaint.setStrokeWidth(8);        Path path = new Path();        //起点        path.moveTo(start.x, start.y);        //贝塞尔曲线中间途径的点        path.cubicTo(fingerPointOne.x, fingerPointOne.y, fingerPointTwo.x, fingerPointTwo.y, end.x, end.y);        canvas.drawPath(path, mPaint);    }}
0 0