源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

Android贝塞尔曲线初步学习第一课

  • 时间:2021-12-01 19:43 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:Android贝塞尔曲线初步学习第一课
贝塞尔曲线有一阶、二阶、三阶、N阶 一阶就是一条直线,有起点终点,没有控制点,对应方法就是
canvas.drawLine(float startX, float startY, float stopX, float stopY, @NonNull Paint paint) ;
二阶为曲线,有起点终点,一个控制点,对应方法就是
path.quadTo(float x1, float y1, float x2, float y2);
其中x1、y1为控制点坐标, x2、y2为终点坐标,效果如下: [img]http://files.jb51.net/file_images/article/201703/2017031310240220.jpg[/img] 三阶由俩个控制点控制,对应方法就是
path.cubicTo(float x1, float y1, float x2, float y2, float x3, float y3);
其中x1、y1、x2、y2为两个控制点坐标, x3、y3为终点坐标,效果如下: [img]http://files.jb51.net/file_images/article/201703/2017031310240221.jpg[/img] 做一个demo巩固一下用法: [img]http://files.jb51.net/file_images/article/201703/2017031310240322.gif[/img] 新建一个SecondBezierView继承View,重写构造方法、初始化画笔、固定起点和终点的坐标,重写onTouchEvent()方法获取当前点击的点为控制点:
 @Override
 public boolean onTouchEvent(MotionEvent event) {
 switch (event.getAction()) {
 case MotionEvent.ACTION_MOVE:
 mControlX = event.getX();
 mControlY = event.getY();
 invalidate();
 break;
 }
 return true;
 }
在onDraw()方法中画点、画连接线、画文本、画二阶贝塞尔曲线
 @Override
 protected void onDraw(Canvas canvas) {
 super.onDraw(canvas);
 canvas.drawCircle(mStartX, mStartY, 8, mLinePaint);
 canvas.drawText("起点", mStartX, mStartY, mLinePaint);
 canvas.drawCircle(mEndX, mEndY, 8, mLinePaint);
 canvas.drawText("终点", mEndX, mEndY, mLinePaint);
 canvas.drawCircle(mControlX, mControlY, 8, mLinePaint);
 canvas.drawText("控制点", mControlX, mControlY, mLinePaint);
 canvas.drawLine(mStartX, mStartY, mControlX, mControlY, mLinePaint);
 canvas.drawLine(mEndX, mEndY, mControlX, mControlY, mLinePaint);

 mBezierPath.reset();//因为不断重绘,path的路径也要重置,不然页面上会显示很多条线
 mBezierPath.moveTo(mStartX, mStartY);//移至起点
 mBezierPath.quadTo(mControlX, mControlY, mEndX, mEndY);//二阶贝塞尔曲线,传入控制点和终点坐标
 canvas.drawPath(mBezierPath, mBezierPaint);
 }

最后添加一个回弹的动画,用的是OvershootInterpolator插值器,在onTouchEvent的MotionEvent.ACTION_UP中:
 case MotionEvent.ACTION_UP:
 ValueAnimator animX = ValueAnimator.ofFloat(mControlX, getWidth() / 2);
 animX.setDuration(500);
 animX.setInterpolator(new OvershootInterpolator());
 animX.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
 @Override
 public void onAnimationUpdate(ValueAnimator animation) {
 mControlX = (float) animation.getAnimatedValue();
 invalidate();
 }
 });
 animX.start();
 ValueAnimator animY = ValueAnimator.ofFloat(mControlY, getHeight() / 2);
 animY.setDuration(500);
 animY.setInterpolator(new OvershootInterpolator());
 animY.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
 @Override
 public void onAnimationUpdate(ValueAnimator animation) {
 mControlY = (float) animation.getAnimatedValue();
 invalidate();
 }
 });
 animY.start();
 break;
再来个三阶的 [img]http://files.jb51.net/file_images/article/201703/2017031310240323.gif[/img] 主要就是用到了多点触控:
 private boolean mIsSecondPoint = false;

 @Override
 public boolean onTouchEvent(MotionEvent event) {
 switch (event.getAction() & MotionEvent.ACTION_MASK) {//多点触控
 case MotionEvent.ACTION_POINTER_DOWN:
 mIsSecondPoint = true;
 break;
 case MotionEvent.ACTION_POINTER_UP:
 mIsSecondPoint = false;
 break;
 case MotionEvent.ACTION_MOVE:
 mControlX1 = event.getX(0);//获取控制点1的横纵坐标
 mControlY1 = event.getY(0);
 if (mIsSecondPoint) {
  mControlX2 = event.getX(1);//获取控制点2的横纵坐标
  mControlY2 = event.getY(1);
 }
 invalidate();
 break;
 }
 return true;
 }

然后再onDraw()中画三阶贝塞尔曲线
 mBezierPath.reset();
 mBezierPath.moveTo(mStartX, mStartY);
 mBezierPath.cubicTo(mControlX1, mControlY1, mControlX2, mControlY2, mEndX, mEndY);
 canvas.drawPath(mBezierPath, mBezierPaint);
大功告成,打完收工。 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程素材网。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部