当前位置: 移动技术网 > 移动技术>移动开发>Android > Android贝塞尔曲线初步学习第一课

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

2019年07月24日  | 移动技术网移动技术  | 我要评论

贝塞尔曲线有一阶、二阶、三阶、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为终点坐标,效果如下:

这里写图片描述

三阶由俩个控制点控制,对应方法就是

path.cubicto(float x1, float y1, float x2, float y2, float x3, float y3);

其中x1、y1、x2、y2为两个控制点坐标, x3、y3为终点坐标,效果如下:

这里写图片描述

做一个demo巩固一下用法:

这里写图片描述

新建一个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;

再来个三阶的

这里写图片描述

主要就是用到了多点触控:

 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);

大功告成,打完收工。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网