最新消息:文章中包含代码时,请遵守代码高亮规范!

Android Bezier之二阶Bezier曲线【原创】

Android 李, 泰愚 201浏览 0评论

Android开发中,难免会遇到许多动画,绘图方面的需求,今天来记录一下之前在慕课上学习到的Bezier曲线方面的内容,关于Bezier曲线,百度百科叙述的很清楚,而且它的数学公式也有明确的介绍。在Android中的Bezier曲线的应用也很广泛,今天记录一下二阶Bezier曲线的实现。

简单来说,二阶Bezier曲线有三个点,一个起始点,一个终点,和一个控制点,由控制点的位置决定起始点和终点之间的平滑曲线连接。可以从这个网站来看Bezier曲线,https://myst729.github.io/bezier-curve/

实现是自定义一个View,在里面进行二阶Bezier的绘制

需要定义的变量如下,

private float mStartPointX;
private float mStartPointY;

private float mEndPointX;
private float mEndPointY;

private float mFlagPointX;
private float mFlagPointY;

private Path mPath;

private Paint mPaintBezier;
private Paint mPaintFlag;
private Paint mPaintFlagText;

开始点,终点,控制点,以及绘制Bezier需要的Path,还有三个画笔,分别是画曲线,点以及点旁边的介绍文字。

构造方法如下,

public SecondBezierView(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    mPaintBezier = new Paint(Paint.ANTI_ALIAS_FLAG);
    mPaintBezier.setStrokeWidth(8);
    mPaintBezier.setStyle(Paint.Style.STROKE);

    mPaintFlag = new Paint(Paint.ANTI_ALIAS_FLAG);
    mPaintFlag.setStrokeWidth(3);
    mPaintFlag.setStyle(Paint.Style.STROKE);

    mPaintFlagText = new Paint(Paint.ANTI_ALIAS_FLAG);
    mPaintFlagText.setStyle(Paint.Style.STROKE);
    mPaintFlagText.setTextSize(20);
}

构造方法没有太多需要叙述,就是变量的初始化。onSizeChanged方法如下

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    mStartPointX = w/4;
    mStartPointY = h/2 - 200;

    mEndPointX = w*3/4;
    mEndPointY = h/2 - 200;

    mFlagPointX = w/2;
    mFlagPointY = h/2 - 300;

    mPath = new Path();
}

此方法中,确定初始点和终点,以及控制点第一次的坐标,还有就是Path变量的初始化。在onDraw方法中,

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    mPath.reset();
    mPath.moveTo(mStartPointX, mStartPointY);
    mPath.quadTo(mFlagPointX, mFlagPointY, mEndPointX, mEndPointY);

    canvas.drawPoint(mStartPointX, mStartPointY, mPaintFlag);
    canvas.drawText("起点", mStartPointX, mStartPointY, mPaintFlagText);
    canvas.drawPoint(mEndPointX, mEndPointY, mPaintFlag);
    canvas.drawText("终点", mEndPointX, mEndPointY, mPaintFlagText);
    canvas.drawPoint(mFlagPointX, mFlagPointY, mPaintFlag);
    canvas.drawText("控制点", mFlagPointX, mFlagPointY, mPaintFlagText);

    canvas.drawLine(mStartPointX, mStartPointY, mFlagPointX, mFlagPointY, mPaintFlag);
    canvas.drawLine(mEndPointX, mEndPointY, mFlagPointX, mFlagPointY, mPaintFlag);

    canvas.drawPath(mPath, mPaintBezier);
}

先将path的起点移动到起始点,调用quaTo方法绘制二阶Bezier曲线。且绘制三个点旁的介绍文字,起始点,终点分别和控制点用直线连接,看起来更加直观。

最后重写onTouchEvent方法,

@Override
public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_MOVE:
            mFlagPointX = event.getX();
            mFlagPointY = event.getY();
            invalidate();
            break;
    }
    return true;
}

这里是为了随着手指位置更新控制点坐标,且调用invalidate方法进行重绘,能看到控制点不同时刻的二阶Bezier曲线。

布局中使用时如上图,进入界面时的绘图,当手机点击并移动时,曲线也会随之变化。

转载时请注明出处及相应链接,本文永久地址:http://blog.it985.com/22112.html


pay_weixin
pay_weixin
微信打赏
pay_weixin
支付宝打赏
感谢您对作者rick的打赏,我们会更加努力!    如果您想成为作者,请点我

您必须 登录 才能发表评论!