贝塞尔曲线学习【1】

来源:互联网 发布:淘宝面试问题及答案 编辑:程序博客网 时间:2024/06/06 19:53

贝塞尔曲线学习【1】

今天学习了贝塞尔曲线的相关内容
特别感谢 http://blog.csdn.net/z82367825/article/details/51599245 博文。
具体的理论知识就不写了。
在此处记录下 修改过的 波浪图(由原来的一条增加为3条交替变化)。如下图所示。具体实现可以参考上面的文章。
这里写图片描述
这里是绘制了三条贝塞尔曲线组合而成的效果。代码如下:

package com.zero.bezier.widget.wave;import android.animation.ValueAnimator;import android.content.Context;import android.graphics.Canvas;import android.graphics.LinearGradient;import android.graphics.Paint;import android.graphics.Path;import android.graphics.PointF;import android.graphics.Shader;import android.os.Handler;import android.os.Message;import android.util.AttributeSet;import android.view.View;import android.view.animation.Animation;import android.view.animation.LinearInterpolator;public class WaveView extends View {    /**     * 波峰     */    private float mWavePeak = 35f;    /**     * 波槽     */    private float mWaveTrough = 35f;    /**     * 水位     */    private float mWaveHeight = 350f;    private Paint mPaintWave1;    private Path mPathWave1;    private int mWaterColorWave1 = 0x990000FF;    private Paint mPaintWave2;    private Path mPathWave2;    private int mWaterColorWave2 = 0x550000FF;    private Paint mPaintWave3;    private Path mPathWave3;    private int mWaterColorWave3 = 0x220000FF;    public WaveView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init();    }    public WaveView(Context context, AttributeSet attrs) {        super(context, attrs);        init();    }    public WaveView(Context context) {        super(context);        init();    }    private void init() {        mPathWave1 = new Path();        mPaintWave1 = new Paint();        mPaintWave1.setAntiAlias(true);        //mPaintWave1.setStyle(Paint.Style.FILL);        //mPaintWave1.setColor(mWaterColorWave1);        //mPaintWave1.setColor(getResources().getColor(android.R.color.holo_blue_bright));        mPathWave2 = new Path();        mPaintWave2 = new Paint();        mPaintWave2.setAntiAlias(true);        mPaintWave2.setStyle(Paint.Style.FILL);        mPaintWave2.setColor(mWaterColorWave2);        //mPaintWave2.setColor(getResources().getColor(android.R.color.holo_red_light));        mPathWave3 = new Path();        mPaintWave3 = new Paint();        mPaintWave3.setAntiAlias(true);        mPaintWave3.setStyle(Paint.Style.FILL);        mPaintWave3.setColor(mWaterColorWave3);        //mPaintWave3.setColor(getResources().getColor(android.R.color.holo_green_light));        LinearGradient linearGradient = new LinearGradient(                0,                0,                720,                720,                mWaterColorWave1,                mWaterColorWave3,                Shader.TileMode.CLAMP);        mPaintWave1.setShader(linearGradient);    }    private float mWidth, mHeight;    private PointF mWave1Start;    private PointF mWave1Left1, mWave1Left2, mWave1First, mWave1Second, mWave1Right;    private PointF mWave1ControlLeft1, mWave1ControlLeft2, mWave1ControlFirst, mWave1ControlSecond;    private PointF mWave2Start;    private PointF mWave2Left1, mWave2Left2, mWave2First, mWave2Second, mWave2Right;    private PointF mWave2ControlLeft1, mWave2ControlLeft2, mWave2ControlFirst, mWave2ControlSecond;    private PointF mWave3Start;    private PointF mWave3Left1, mWave3Left2, mWave3First, mWave3Second, mWave3Right;    private PointF mWave3ControlLeft1, mWave3ControlLeft2, mWave3ControlFirst, mWave3ControlSecond;    private boolean mIsRunning = false;    private boolean mHasInit = false;    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        if (!mHasInit) {            mWidth = w;            mHeight = h;            mHasInit = true;        }        super.onSizeChanged(w, h, oldw, oldh);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        if (!mIsRunning || !mHasInit)            return;        mPathWave1.reset();        mPathWave1.moveTo(mWave1Left1.x, mWave1Left1.y);        mPathWave1.quadTo(mWave1ControlLeft1.x, mWave1ControlLeft1.y, mWave1Left2.x, mWave1Left2.y);        mPathWave1.quadTo(mWave1ControlLeft2.x, mWave1ControlLeft2.y, mWave1First.x, mWave1First.y);        mPathWave1.quadTo(mWave1ControlFirst.x, mWave1ControlFirst.y, mWave1Second.x, mWave1Second.y);        mPathWave1.quadTo(mWave1ControlSecond.x, mWave1ControlSecond.y, mWave1Right.x, mWave1Right.y);        mPathWave1.lineTo(mWave1Right.x, mHeight);        mPathWave1.lineTo(mWave1Left1.x, mHeight);        mPathWave1.lineTo(mWave1Left1.x, mWave1Left1.y);        canvas.drawPath(mPathWave1, mPaintWave1);        mPathWave2.reset();        mPathWave2.moveTo(mWave2Left1.x, mWave2Left1.y);        mPathWave2.quadTo(mWave2ControlLeft1.x, mWave2ControlLeft1.y, mWave2Left2.x, mWave2Left2.y);        mPathWave2.quadTo(mWave2ControlLeft2.x, mWave2ControlLeft2.y, mWave2First.x, mWave2First.y);        mPathWave2.quadTo(mWave2ControlFirst.x, mWave2ControlFirst.y, mWave2Second.x, mWave2Second.y);        mPathWave2.quadTo(mWave2ControlSecond.x, mWave2ControlSecond.y, mWave2Right.x, mWave2Right.y);        mPathWave2.lineTo(mWave2Right.x, mHeight);        mPathWave2.lineTo(mWave2Left1.x, mHeight);        mPathWave2.lineTo(mWave2Left1.x, mWave2Left1.y);        canvas.drawPath(mPathWave2, mPaintWave2);        mPathWave3.reset();        mPathWave3.moveTo(mWave3Left1.x, mWave3Left1.y);        mPathWave3.quadTo(mWave3ControlLeft1.x, mWave3ControlLeft1.y, mWave3Left2.x, mWave3Left2.y);        mPathWave3.quadTo(mWave3ControlLeft2.x, mWave3ControlLeft2.y, mWave3First.x, mWave3First.y);        mPathWave3.quadTo(mWave3ControlFirst.x, mWave3ControlFirst.y, mWave3Second.x, mWave3Second.y);        mPathWave3.quadTo(mWave3ControlSecond.x, mWave3ControlSecond.y, mWave3Right.x, mWave3Right.y);        mPathWave3.lineTo(mWave3Right.x, mHeight);        mPathWave3.lineTo(mWave3Left1.x, mHeight);        mPathWave3.lineTo(mWave3Left1.x, mWave3Left1.y);        canvas.drawPath(mPathWave3, mPaintWave3);    }    private void reset() {        mWave1Start = new PointF(-mWidth, mHeight - mWaveHeight);        mWave1Left1 = new PointF(-mWidth, mHeight - mWaveHeight);        mWave1Left2 = new PointF(-mWidth / 2f, mHeight - mWaveHeight);        mWave1First = new PointF(0, mHeight - mWaveHeight);        mWave1Second = new PointF(mWidth / 2f, mHeight - mWaveHeight);        mWave1Right = new PointF(mWidth, mHeight - mWaveHeight);        mWave1ControlLeft1 = new PointF(mWave1Left1.x + mWidth / 4f, mWave1Left1.y + mWavePeak);        mWave1ControlLeft2 = new PointF(mWave1Left2.x + mWidth / 4f, mWave1Left2.y - mWaveTrough);        mWave1ControlFirst = new PointF(mWave1First.x + mWidth / 4f, mWave1First.y + mWavePeak);        mWave1ControlSecond = new PointF(mWave1Second.x + mWidth / 4f, mWave1Second.y - mWaveTrough);        mWave2Start = new PointF(-mWidth, mHeight - mWaveHeight);        mWave2Left1 = new PointF(-mWidth, mHeight - mWaveHeight);        mWave2Left2 = new PointF(-mWidth / 2f, mHeight - mWaveHeight);        mWave2First = new PointF(0, mHeight - mWaveHeight);        mWave2Second = new PointF(mWidth / 2f, mHeight - mWaveHeight);        mWave2Right = new PointF(mWidth, mHeight - mWaveHeight);        mWave2ControlLeft1 = new PointF(mWave2Left1.x + mWidth / 4f, mWave2Left1.y + mWavePeak);        mWave2ControlLeft2 = new PointF(mWave2Left2.x + mWidth / 4f, mWave2Left2.y - mWaveTrough);        mWave2ControlFirst = new PointF(mWave2First.x + mWidth / 4f, mWave2First.y + mWavePeak);        mWave2ControlSecond = new PointF(mWave2Second.x + mWidth / 4f, mWave2Second.y - mWaveTrough);        mWave3Start = new PointF(-mWidth, mHeight - mWaveHeight);        mWave3Left1 = new PointF(-mWidth, mHeight - mWaveHeight);        mWave3Left2 = new PointF(-mWidth / 2f, mHeight - mWaveHeight);        mWave3First = new PointF(0, mHeight - mWaveHeight);        mWave3Second = new PointF(mWidth / 2f, mHeight - mWaveHeight);        mWave3Right = new PointF(mWidth, mHeight - mWaveHeight);        mWave3ControlLeft1 = new PointF(mWave3Left1.x + mWidth / 4f, mWave3Left1.y + mWavePeak);        mWave3ControlLeft2 = new PointF(mWave3Left2.x + mWidth / 4f, mWave3Left2.y - mWaveTrough);        mWave3ControlFirst = new PointF(mWave3First.x + mWidth / 4f, mWave3First.y + mWavePeak);        mWave3ControlSecond = new PointF(mWave3Second.x + mWidth / 4f, mWave3Second.y - mWaveTrough);    }    private class WaveHandler extends Handler {        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            if (msg.what == ANIM_START) {                reset();                startAnimWave1();                startAnimWave2();                startAnimWave3();                mIsRunning = true;            }        }    }    private WaveHandler mWaveHandler = new WaveHandler();    private static final int ANIM_START = 1;    public void setRunning() {        new Thread(new Runnable() {            @Override            public void run() {                while (!mHasInit) {                    try {                        Thread.sleep(50);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }                mWaveHandler.sendEmptyMessage(ANIM_START);            }        }).start();    }    private void startAnimWave1() {        ValueAnimator valueAnimator = ValueAnimator.ofFloat(mWave1Start.x, 0);        valueAnimator.setInterpolator(new LinearInterpolator());        valueAnimator.setDuration(3000);        valueAnimator.setRepeatCount(Animation.INFINITE);        //动画效果重复//        valueAnimator.setRepeatMode(Animation.RESTART);        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                mWave1Left1.x = (float) animation.getAnimatedValue();                mWave1Left2 = new PointF(mWave1Left1.x + mWidth / 2f, mHeight - mWaveHeight);                mWave1First = new PointF(mWave1Left2.x + mWidth / 2f, mHeight - mWaveHeight);                mWave1Second = new PointF(mWave1First.x + mWidth / 2f, mHeight - mWaveHeight);                mWave1Right = new PointF(mWave1Second.x + mWidth / 2f, mHeight - mWaveHeight);                mWave1ControlLeft1 = new PointF(mWave1Left1.x + mWidth / 4f, mWave1Left1.y + mWavePeak);                mWave1ControlLeft2 = new PointF(mWave1Left2.x + mWidth / 4f, mWave1Left2.y - mWaveTrough);                mWave1ControlFirst = new PointF(mWave1First.x + mWidth / 4f, mWave1First.y + mWavePeak);                mWave1ControlSecond = new PointF(mWave1Second.x + mWidth / 4f, mWave1Second.y - mWaveTrough);                invalidate();            }        });        valueAnimator.start();    }    private void startAnimWave2() {        ValueAnimator valueAnimator1 = ValueAnimator.ofFloat(mWave2Start.x, 0);        valueAnimator1.setInterpolator(new LinearInterpolator());        valueAnimator1.setDuration(3000);        valueAnimator1.setRepeatCount(Animation.INFINITE);        valueAnimator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                mWave2Left1.x = (float) animation.getAnimatedValue();                mWave2Left2 = new PointF(mWave2Left1.x + mWidth / 2f, mHeight - mWaveHeight);                mWave2First = new PointF(mWave2Left2.x + mWidth / 2f, mHeight - mWaveHeight);                mWave2Second = new PointF(mWave2First.x + mWidth / 2f, mHeight - mWaveHeight);                mWave2Right = new PointF(mWave2Second.x + mWidth / 2f, mHeight - mWaveHeight);                mWave2ControlLeft1 = new PointF(mWave2Left1.x + mWidth / 4f, mWave2Left1.y + mWavePeak);                mWave2ControlLeft2 = new PointF(mWave2Left2.x + mWidth / 4f, mWave2Left2.y - mWaveTrough);                mWave2ControlFirst = new PointF(mWave2First.x + mWidth / 4f, mWave2First.y + mWavePeak);                mWave2ControlSecond = new PointF(mWave2Second.x + mWidth / 4f, mWave2Second.y - mWaveTrough);                invalidate();            }        });        valueAnimator1.setStartDelay(-1800);        valueAnimator1.start();    }    private void startAnimWave3() {        ValueAnimator valueAnimator1 = ValueAnimator.ofFloat(mWave3Start.x, 0);        valueAnimator1.setInterpolator(new LinearInterpolator());        valueAnimator1.setDuration(3000);        valueAnimator1.setRepeatCount(Animation.INFINITE);        valueAnimator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                mWave3Left1.x = (float) animation.getAnimatedValue();                mWave3Left2 = new PointF(mWave3Left1.x + mWidth / 2f, mHeight - mWaveHeight);                mWave3First = new PointF(mWave3Left2.x + mWidth / 2f, mHeight - mWaveHeight);                mWave3Second = new PointF(mWave3First.x + mWidth / 2f, mHeight - mWaveHeight);                mWave3Right = new PointF(mWave3Second.x + mWidth / 2f, mHeight - mWaveHeight);                mWave3ControlLeft1 = new PointF(mWave3Left1.x + mWidth / 4f, mWave3Left1.y + mWavePeak);                mWave3ControlLeft2 = new PointF(mWave3Left2.x + mWidth / 4f, mWave3Left2.y - mWaveTrough);                mWave3ControlFirst = new PointF(mWave3First.x + mWidth / 4f, mWave3First.y + mWavePeak);                mWave3ControlSecond = new PointF(mWave3Second.x + mWidth / 4f, mWave3Second.y - mWaveTrough);                invalidate();            }        });        valueAnimator1.setStartDelay(-800);        valueAnimator1.start();    }}

此处只记录下自己探索的内容:
1、由一条曲线扩充为多条,是开了多个ValueAnimator来invalidate()视图。
2、为了制造视差,在另外两条曲线的ValueAnimator实例中设定了.setStartDelay()值,使动画的发生值滞后(如果设定正值)或者提前(如果设定负值)。此处,设定了负值,即相位提前,避免在第一个曲线动画开始后,其他曲线存在滞后显示的情况
3、绘制path时,替代使用solid颜色,而是使用gradient实现渐变色
4、下面要探索下,是否 可以只使用一个ValueAnimator即可实现多个贝塞尔曲线交叠显示

原创粉丝点击