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为终点坐标,效果如下:
三阶由俩个控制点控制,对应方法就是
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);
大功告成,打完收工。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。