欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2023-11-21 10:30:10
贝塞尔曲线有一阶、二阶、三阶、n阶 一阶就是一条直线,有起点终点,没有控制点,对应方法就是 canvas.drawline(float startx, f...

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

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

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

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

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

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

做一个demo巩固一下用法:

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

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

再来个三阶的

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

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

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

大功告成,打完收工。

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