贝塞尔曲线(一) 认识
来源:互联网 发布:奶酪陷阱 知乎 编辑:程序博客网 时间:2024/05/22 13:05
转载请注明出处:http://blog.csdn.net/darling_R/article/details/68969530
看了徐医宜生 的视频,现在练习了一下贝塞尔曲线,其实挺简单的。下面来看看代码吧
首先借用官方的一个图来演示一下什么是贝塞尔曲线
也可以去[这里]看详细介绍
(https://en.wikipedia.org/wiki/B%C3%A9zier_curve#Linear_curves)
二阶贝塞尔曲线
三阶贝塞尔曲线
二阶效果图:
主要弄清楚 起点 、终点、控制点,然后使用Android提供的贝塞尔曲线api就行了,
二阶的:在onDraw 方法中调用 mPath.quadTo(mFlagPointX, mFlagPointY, mEndPointX, mEndPointY);
前两个参数就是 控制点的坐标,后两个则是终点坐标,起点坐标在初始化path时就确定了,因为绘制曲线,要调用drawpath方法,所以在此之前要定义一个Path,并且在绘制之前,调用reset方法重置,并且,将path移动到起点 mPath.moveTo(mStartPointX,mStartPointY);
重写 OnTouch方法,
case MotionEvent.ACTION_MOVE: mFlagPointX = event.getX(); mFlagPointY = event.getY(); invalidate(); break;
在手指移动的过程中,记录控制点的坐标,可以让控制点随着手指的移动而移动
在抬起的事件中添加一个动画效果:
case MotionEvent.ACTION_UP: float mTempX = mStartPointX + (mEndPointX - mStartPointX) / 2; float mTempY = mStartPointY + (mEndPointY - mStartPointY) / 2; ValueAnimator valueAnimatorX = ValueAnimator.ofFloat(mFlagPointX,mTempX); valueAnimatorX.setDuration(500); valueAnimatorX.setInterpolator(new OvershootInterpolator()); valueAnimatorX.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mFlagPointX = (float) animation.getAnimatedValue(); invalidate(); } }); valueAnimatorX.start(); ValueAnimator valueAnimatorY = ValueAnimator.ofFloat(mFlagPointY,mTempY); valueAnimatorY.setDuration(500); valueAnimatorY.setInterpolator(new OvershootInterpolator()); valueAnimatorY.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mFlagPointY = (float) animation.getAnimatedValue(); invalidate(); } }); valueAnimatorY.start(); break;
三阶效果图:
三阶贝塞尔曲线跟二阶差不多,唯一多出来的知识点就是涉及到多点触控,在OnTouch事件里面,
case MotionEvent.ACTION_POINTER_DOWN://监听第二根手指按下 isSecond = true; break; //多点触控 抬起 case MotionEvent.ACTION_POINTER_UP: isSecond = false; break;
mPath.cubicTo(mFlagPointOneX, mFlagPointOneY,mFlagPointTwoX,mFlagPointTwoY, mEndPointX, mEndPointY);
api也有点不同,就是多了控制点的坐标,
二阶跟三阶都有两个方法:rQuadTo(),rCubicTo(),这两个里面的参数都是相对坐标,而quadTo()和cubicTo()参数坐标都是绝对坐标,这里需要注意一下;
这里附上三阶的源码,对应的可以看出来二阶的:
public class ThirdBezierView extends View { //起点坐标 private float mStartPointX; private float mStartPointY; //终点坐标 private float mEndPointY; private float mEndPointX; //控制点坐标 private float mFlagPointOneX; private float mFlagPointOneY; private float mFlagPointTwoX; private float mFlagPointTwoY; //曲线画笔 private Paint mBezierPaint; //连线画笔 private Paint mLinePaint; //文字画笔 private Paint mTextPait; // private Path mPath; private boolean isSecond = false;//标志第二个手指是否按下 public ThirdBezierView(Context context) { super(context); } public ThirdBezierView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); mPath = new Path(); mBezierPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mBezierPaint.setColor(0xfff3a344); mBezierPaint.setStrokeWidth(8); mBezierPaint.setStyle(Paint.Style.STROKE); mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG); mLinePaint.setStyle(Paint.Style.STROKE); mTextPait = new Paint(Paint.ANTI_ALIAS_FLAG); mTextPait.setStyle(Paint.Style.STROKE); mTextPait.setTextSize(26); } public ThirdBezierView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); //初始化坐标点 mStartPointX = w / 4; mStartPointY = h / 3; mEndPointX = 3 * w / 4; mEndPointY = h / 3; mFlagPointOneX = w / 2 - 200; mFlagPointOneY = h / 4; mFlagPointTwoX = w / 2 + 200; mFlagPointTwoY = h / 4; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPath.reset(); mPath.moveTo(mStartPointX, mStartPointY); //链接起点与控制点 canvas.drawLine(mStartPointX, mStartPointY, mFlagPointOneX, mFlagPointOneY, mLinePaint); canvas.drawLine(mFlagPointOneX, mFlagPointOneY, mFlagPointTwoX, mFlagPointTwoY, mLinePaint); canvas.drawLine(mFlagPointTwoX, mFlagPointTwoY, mEndPointX, mEndPointY, mLinePaint); canvas.drawText("起点",mStartPointX,mStartPointY,mTextPait); canvas.drawText("控制点",mFlagPointOneX,mFlagPointOneY,mTextPait); canvas.drawText("控制点",mFlagPointTwoX,mFlagPointTwoY,mTextPait); canvas.drawText("终点",mEndPointX,mEndPointY,mTextPait); mPath.cubicTo(mFlagPointOneX, mFlagPointOneY,mFlagPointTwoX,mFlagPointTwoY, mEndPointX, mEndPointY); canvas.drawPath(mPath, mBezierPaint); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction() &MotionEvent.ACTION_MASK) { //多点触控标志按下 case MotionEvent.ACTION_POINTER_DOWN: isSecond = true; break; //多点触控 抬起 case MotionEvent.ACTION_POINTER_UP: isSecond = false; break; case MotionEvent.ACTION_MOVE: mFlagPointOneX = event.getX(0); mFlagPointOneY = event.getY(0); if(isSecond){ mFlagPointTwoX = event.getX(1); mFlagPointTwoY = event.getY(1); } invalidate(); break; } return true; }}
- 贝塞尔曲线(一) 认识
- 曲线之美(一)贝塞尔曲线
- 曲线之美(一)贝塞尔曲线
- 曲线之美(一)贝塞尔曲线
- 曲线之美(一)贝塞尔曲线
- Itween 贝塞尔曲线(一)
- iOS贝塞尔曲线学习笔记(一)
- Android 贝塞尔曲线(一)弹性圆
- 【Android】贝塞尔曲线的艺术(一)
- Android 贝塞尔曲线简单应用(一)
- SVG 贝塞尔曲线学习一
- 认识硬盘(一)
- 软件工程(一)认识
- UML(一)认识
- hadoop(一):认识
- 认识BootStrap(一)
- 认识Uboot(一)
- 认识Java(一)
- css中脱离文档流解惑
- AngularJS自定义指令directive:父类scope和指令中scope之间的通信
- 传项目到GitHub上没有.xcodeproj文件的问题
- 【机器学习算法】机器学习(周志华西瓜书)参考答案总目录
- 第六周周记
- 贝塞尔曲线(一) 认识
- fork()函数详解
- 用数组来处理求Fibonacci数列问题
- java properties解析
- Linux系统编程3.时间概念
- js日期操作之根据指定格式获取日期
- DOM 编程艺术 实用代码段
- 谈谈我对京东的认识(4):电商只有综合型电商,没有垂直电商
- 使用Java实现面向对象编程--集合框架