您的位置:首页 > 移动开发 > Android开发

android自定义View基础系列二(贝塞尔曲线)

2017-02-28 17:42 232 查看
前言:

好久没写技术博客了。android很多酷炫的自定义VIew效果和贝塞尔曲线相关,像水波纹效、火箭效果等,从本篇开始将研究和使用贝塞尔曲线以及xfermode。相应的效果,以后也会以gif图片展示,更为直观。

概要:

本篇文章主要介绍贝塞尔曲线,以及对于二阶和三阶贝塞尔曲线的简单使用。

正文:

1,什么是贝塞尔曲线

贝塞尔曲线,又称贝兹曲线或者贝济埃曲线,是应用于二位图形应用程序的数学曲线。贝塞尔曲线是由线段和节点组成的,节点是可以拖动的支点,线段像可以伸缩的橡皮筋。是计算机图形学当中比较重要的参数曲线。

这里盗两张图,我们结合常用的一阶贝塞尔曲线、二阶贝塞尔曲线和三阶贝塞尔曲线来理解下:

1)一阶贝塞尔曲线:

          






一阶贝塞尔曲线展现的是一条两点之间的直线。B(t)是t时间下,点的坐标,P0为起点、P1为终点。

t时间点的坐标 B(t)=P0 + (P1 - P0)*t = (1-t)*P0 + P1*t

2)二阶贝塞尔曲线:

   






二阶贝塞尔曲线展现的是一条抛物线。P0至P1之间的连续点Q0,描述一条线段,P1至P2之间的连续点Q1,描述一条线段,Q0至Q1之间的连续点B(t),描述一条二阶贝塞尔曲线。如图Q0视为绿色线段在P0~P1上的点,Q1视为绿色线段在P1~P2上的点。

附上超吃藕手写推算过程





3)三阶贝塞尔曲线:

     


               


具体原理以及推算公式可以参照二阶贝塞尔曲线的推算方式。

贝塞尔曲线通用公式:



说明:P0点到P1点的连续点直线和贝塞尔曲线相切。

2,贝塞尔曲线在android中的相关使用

Android中的Path类提供了绘制贝塞尔曲线的方法。


1)二阶贝塞尔曲线:

//设置Path移动到起始位置100,300
mPath.moveTo(100,300);
//设置辅助点250,300 设置终点400,300
mPath.quadTo(250,300,400,300);效果如图:



现在知识一条直线,实现抛物线的效果,我们需要结合onTouch事件,将辅助点的坐标改为动态的:

@Override
protected void onDraw(Canvas canvas) {

mPath.reset();
mPaint.setColor(Color.parseColor("#ff0000"));
mPaint.setStrokeWidth(5);
mPaint.setStyle(Paint.Style.STROKE);

//设置Path移动到起始位置100,300
mPath.moveTo(100,300);
//设置辅助点250,300 设置终点400,300
mPath.quadTo(supX,supY,400,300);
canvas.drawPath(mPath,mPaint);
super.onDraw(canvas);

}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch(event.getAction()){
case MotionEvent.ACTION_MOVE:
supX = event.getX();
supY = event.getY();
invalidate();
break;
default:
break;
}
return true;
}
此时的效果:



现在曲线随着辅助点变化,但是辅助点的位置不够直观,没有办法看出辅助点和抛物线的关系,下面把辅助点显示出来。

canvas.drawPoint(supX,supY,mPaint);现在我们也可以看到辅助点了:



2)三阶贝塞尔曲线:

使用Path类中的cubilTo方法。

cubicTo(float x1, float y1, float x2, float y2,float x3, float y3)x1,y1是第一个辅助点的坐标;x2,y2是第二个辅助点的坐标;x3,y3是终点的坐标。
直接绘制出效果和辅助点:

@Override
protected void onDraw(Canvas canvas) {

mPath.reset();
mPaint.setColor(Color.parseColor("#ff0000"));
mPaint.setStrokeWidth(10);
mPaint.setStyle(Paint.Style.STROKE);

//设置Path移动到起始位置100,300
mPath.moveTo(100,300);
//设置辅助点250,500 设置辅助点550,150 设置终点800,300
mPath.cubicTo(250,500,550,150,800,300);
canvas.drawPath(mPath,mPaint);

//绘制第一个辅助点
canvas.drawPoint(250,500,mPaint);
//绘制第二个辅助点
canvas.drawPoint(550,150,mPaint);

super.onDraw(canvas);

}


关于贝塞尔曲线的使用,实现水波纹等效果,会在下一篇介绍。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: