Android 贝塞尔曲线详解释和贝塞尔曲线路径动画(一)(看完包你会理解)

工作这么久,第一次写博客,说来也惭愧,在创业公司没时间写博客啊,好不容易闲下来,就把贝塞尔整理下,写的很简单 只是为了更好地理解

首先看下效果图

                Android 贝塞尔曲线详解释和贝塞尔曲线路径动画(一)(看完包你会理解)                    

这里做下简单介绍 这是 一阶贝塞尔曲线 ,其实很简单需要三个点,起点 控制点 和终点


path.moveTo(start.x, start.y);

path.quadTo(control.x, control.y, end.x, end.y);


//moveTo 是将画笔放到这个位置 

//quadTo(x1,y1,x2,y2) x1 y1 是控制点的坐标 也就是效果图中鼠标那个点

//x2 y2 是终点的坐标 

很简单吧 

接下来看二阶效果图

                                       Android 贝塞尔曲线详解释和贝塞尔曲线路径动画(一)(看完包你会理解)


 这里有四个点 分别是 起点 终点 和两个控制点

path.moveTo(start.x, start.y);
path.cubicTo(control1.x, control1.y, control2.x,control2.y, end.x, end.y);

和一阶一样 只是多个控制点而已 

三阶以及更高只是多个控制点,这里不做解释了。

我把源码发在下面,下一章 贝塞尔路径动画

一阶:

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.util.Log;
import android.view.MotionEvent;
import android.view.View;

/**
 * Created by trc on 17/4/26.
 */

public class Bezier extends View {
    private Paint mPaint;
    private int centerX, centerY;
    /**
     * 贝塞尔曲线 起点 终点 中间的控制点
     */
    private PointF start, end, control;

    public Bezier(Context context) {
        super(context);
        init();
    }

    private void init() {
        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);
        control = new PointF(0, 0);
    }

    public Bezier(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();

    }

    public Bezier(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();

    }

    public Bezier(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();

    }


    @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;
        control.x = centerX;
        control.y = centerY - 100;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // 根据触摸位置更新控制点,并提示重绘
        control.x = event.getX();
        control.y = event.getY();
        invalidate();
        return true;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 绘制数据点和控制点
        mPaint.setColor(Color.GRAY);
        mPaint.setStrokeWidth(40);
        canvas.drawPoint(start.x, start.y, mPaint);
        canvas.drawPoint(end.x, end.y, mPaint);
        canvas.drawPoint(control.x, control.y, mPaint);

        // 绘制辅助线
        mPaint.setStrokeWidth(4);
        canvas.drawLine(start.x, start.y, control.x, control.y, mPaint);
        canvas.drawLine(end.x, end.y, control.x, control.y, mPaint);

        // 绘制贝塞尔曲线
        mPaint.setColor(Color.RED);
        mPaint.setStrokeWidth(8);

        Path path = new Path();
        //moveTo 是将画笔放到这个位置
        path.moveTo(start.x, start.y);
        path.quadTo(control.x, control.y, end.x, end.y);
        // canvas.drawTextOnPath("1234567890", path, 100, 10, mPaint);
        canvas.drawPath(path, mPaint);
    }
}

二阶:

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 trc on 17/4/26.
 * 贝塞尔曲线
 */

public class Bezier2  extends View {
    //
    private Paint mPaint;
    //

    private int centerX, centerY;
    // 起点 终点 第一个控制地那 第二个控制点
    private PointF start, end, control1, control2;
    //
    private boolean mode = true;

    public Bezier2(Context context) {
        this(context, null);

    }

    public Bezier2(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);
        control1 = new PointF(0, 0);
        control2 = new PointF(0, 0);
    }

    public void setMode(boolean mode) {
        this.mode = mode;
    }

    @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;
        control1.x = centerX;
        control1.y = centerY - 100;
        control2.x = centerX;
        control2.y = centerY - 100;

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // 根据触摸位置更新控制点,并提示重绘
        if (mode) {
            control1.x = event.getX();
            control1.y = event.getY();
        } else {
            control2.x = event.getX();
            control2.y = event.getY();
        }


        invalidate();
        return true;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //drawCoordinateSystem(canvas);

        // 绘制数据点和控制点
        mPaint.setColor(Color.GRAY);
        mPaint.setStrokeWidth(30);
        canvas.drawPoint(start.x, start.y, mPaint);
        canvas.drawPoint(end.x, end.y, mPaint);
        canvas.drawPoint(control1.x, control1.y, mPaint);
        canvas.drawPoint(control2.x, control2.y, mPaint);
        mPaint.setStrokeWidth(2);
        canvas.drawText("x:"+String.valueOf(control1.x).substring(0,4)+"y:"+ String.valueOf(control1.y).substring(0,4),control1.x,control1.y-40,mPaint);
        canvas.drawText("x:"+String.valueOf(control2.x).substring(0,4)+"y:"+ String.valueOf(control2.y).substring(0,4),control2.x,control2.y-40,mPaint);

        // 绘制辅助线
        mPaint.setStrokeWidth(4);
        canvas.drawLine(start.x, start.y, control1.x, control1.y, mPaint);
        canvas.drawLine(control1.x, control1.y,control2.x, control2.y, mPaint);
        canvas.drawLine(control2.x, control2.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(control1.x, control1.y, control2.x,control2.y, end.x, end.y);

        canvas.drawPath(path, mPaint);
    }
}