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

Android 使用贝塞尔曲线将多点连成一条平滑的曲线

2016-09-26 10:22 916 查看
本文主要讲解怎么用贝塞尔曲线将多点连成一条平滑的曲线,若不了解贝塞尔曲线的同学可以查看这里

先看效果





确定控制点

使用贝塞尔曲线,我们就要先找出它的控制点,笔者Google后发现了此篇文章,文章中列出了找出控制点的公式



注意:

1.公式中的当前点是线段的起点,文中的当前点指的是线段的终点

2.公式中的a,b代表曲线的弯曲指数,越大代表曲线越弯,一般设置0.16

从公式中可以发现,确定当前点的控制点,需要用到当前点的前两个点和下一个点四个点,那么当当前点是第一个点,第二个点和最后一个点时,我们就无法获取到全部点,那篇文章中又指出



第二种方法过于复杂,文中使用的是第一中方法,即用当前点的值表示无法获取到的点的值,

下面列出代码:

private void measurePath() {
//保存曲线路径
mPath = new Path();
//保存辅助线路径
mAssistPath = new Path();
float prePreviousPointX = Float.NaN;
float prePreviousPointY = Float.NaN;
float previousPointX = Float.NaN;
float previousPointY = Float.NaN;
float currentPointX = Float.NaN;
float currentPointY = Float.NaN;
float nextPointX;
float nextPointY;

final int lineSize = mPointList.size();
for (int valueIndex = 0; valueIndex < lineSize; ++valueIndex) {
if (Float.isNaN(currentPointX)) {
Point point = mPointList.get(valueIndex);
currentPointX = point.x;
currentPointY = point.y;
}
if (Float.isNaN(previousPointX)) {
//是否是第一个点
if (valueIndex > 0) {
Point point = mPointList.get(valueIndex - 1);
previousPointX = point.x;
previousPointY = point.y;
} else {
//是的话就用当前点表示上一个点
previousPointX = currentPointX;
previousPointY = currentPointY;
}
}

if (Float.isNaN(prePreviousPointX)) {
//是否是前两个点
if (valueIndex > 1) {
Point point = mPointList.get(valueIndex - 2);
prePreviousPointX = point.x;
prePreviousPointY = point.y;
} else {
//是的话就用当前点表示上上个点
prePreviousPointX = previousPointX;
prePreviousPointY = previousPointY;
}
}

// 判断是不是最后一个点了
if (valueIndex < lineSize - 1) {
Point point = mPointList.get(valueIndex + 1);
nextPointX = point.x;
nextPointY = point.y;
} else {
//是的话就用当前点表示下一个点
nextPointX = currentPointX;
nextPointY = currentPointY;
}

if (valueIndex == 0) {
// 将Path移动到开始点
mPath.moveTo(currentPointX, currentPointY);
mAssistPath.moveTo(currentPointX, currentPointY);
} else {
// 求出控制点坐标
final float firstDiffX = (currentPointX - prePreviousPointX);
final float firstDiffY = (currentPointY - prePreviousPointY);
final float secondDiffX = (nextPointX - previousPointX);
final float secondDiffY = (nextPointY - previousPointY);
final float firstControlPointX = previousPointX + (lineSmoothness * firstDiffX);
final float firstControlPointY = previousPointY + (lineSmoothness * firstDiffY);
final float secondControlPointX = currentPointX - (lineSmoothness * secondDiffX);
final float secondControlPointY = currentPointY - (lineSmoothness * secondDiffY);
//画出曲线
mPath.cubicTo(firstControlPointX, firstControlPointY, secondControlPointX, secondControlPointY,
currentPointX, currentPointY);
//将控制点保存到辅助路径上
mAssistPath.lineTo(firstControlPointX, firstControlPointY);
mAssistPath.lineTo(secondControlPointX, secondControlPointY);
mAssistPath.lineTo(currentPointX, currentPointY);
}

// 更新值,
prePreviousPointX = previousPointX;
prePreviousPointY = previousPointY;
previousPointX = currentPointX;
previousPointY = currentPointY;
currentPointX = nextPointX;
currentPointY = nextPointY;
}
mPathMeasure = new PathMeasure(mPath, false);
}


参考博
4000
http://blog.csdn.net/u011102153/article/details/52039794 部分源码拷贝了该项目的源码

完整代码 https://github.com/zFxiang/BezierDemo

笔者还属于学习阶段,若文中有错误,还请赐教
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 贝塞尔曲线