贝塞尔曲线相关

mPath.cubicTo(x1, y1, x2, y2, x3, y3) ;

（关注点放在数据点x、y的处理上即可，剩余中点计算的套用现有代码即可

//*****************贝塞尔曲线数据填充=================
private static final int LINEWIDTH = 5;
private static final int LINE_COLOR = 0xffC959A2;

private Paint mPaint;
private Path mPath;
//即将要穿越的点集合
private List<Point> mPoints = new ArrayList<>();
//中点集合
private List<Point> mMidPoints = new ArrayList<>();
//中点的中点集合
private List<Point> mMidMidPoints = new ArrayList<>();
//移动后的点集合(控制点)
private List<Point> mControlPoints = new ArrayList<>();
private List<ContinuousHeartRateAnalysisBean.HrlistBean> hrList;
//大的单位宽度（分6分）
private int unitBigWidth;
//小的单位宽度（分24分）
private int unitSmallWidth;

private void initChart() {
//开始x轴
unitBigWidth = chartWidth / 5;
//x轴单位区间距离
unitSmallWidth = (chartWidth - unitBigWidth) / 24;

mPaint = new Paint();
mPaint.setStyle(Paint.Style.STROKE);// 空心（保持线条）
mPaint.setAntiAlias(true);// 抗锯齿
mPaint.setDither(true);// 防抖动

mPath = new Path();

initPoints();
initMidPoints(this.mPoints);
initMidMidPoints(this.mMidPoints);
initControlPoints(this.mPoints, this.mMidPoints, this.mMidMidPoints);

drawControlPoints(canvas);

// 画贝塞尔曲线
drawBezier(canvas);
}

/**
* 添加即将要穿越的点
*/
private void initPoints() {
mPoints.clear();
for (int i = 0; i < hrList.size(); i++) {
ContinuousHeartRateAnalysisBean.HrlistBean bean = hrList.get(i);
int x = unitBigWidth + Integer.valueOf(bean.getStartTime().substring(9, 11))*unitSmallWidth;
int y = (int) ((maxChartValue - bean.getLivehr())*chartHeight/maxChartValue);

Point point = new Point(x, y);
}
}

/**
* 初始化中点集合
*/
private void initMidPoints(List<Point> points) {
mMidPoints.clear();
for (int i = 0; i < points.size(); i++) {
Point midPoint = null;
if (i == points.size() - 1) {
return;
} else {
midPoint = new Point((points.get(i).x + points.get(i + 1).x) / 2, (points.get(i).y + points.get(i + 1).y) / 2);
}
}
}

/**
* 初始化中点的中点集合
*/
private void initMidMidPoints(List<Point> midPoints) {
mMidMidPoints.clear();
for (int i = 0; i < midPoints.size(); i++) {
Point midMidPoint = null;
if (i == midPoints.size() - 1) {
return;
} else {
midMidPoint = new Point((midPoints.get(i).x + midPoints.get(i + 1).x) / 2, (midPoints.get(i).y + midPoints.get(i + 1).y) / 2);
}
}
}

/**
* 初始化控制点集合
*/
private void initControlPoints(List<Point> points, List<Point> midPoints, List<Point> midMidPoints) {
mControlPoints.clear();
for (int i = 0; i < points.size(); i++) {
if (i == 0 || i == points.size() - 1) {
continue;
} else {
Point before = new Point();
Point after = new Point();
before.x = points.get(i).x - midMidPoints.get(i - 1).x + midPoints.get(i - 1).x;
before.y = points.get(i).y - midMidPoints.get(i - 1).y + midPoints.get(i - 1).y;
after.x = points.get(i).x - midMidPoints.get(i - 1).x + midPoints.get(i).x;
after.y = points.get(i).y - midMidPoints.get(i - 1).y + midPoints.get(i).y;
}
}
}

/** 画控制点 */
private void drawControlPoints(Canvas canvas) {
mPaint.setColor(Color.GRAY);
mPaint.setStrokeWidth(14);
// 画控制点
for (int i = 0; i < mControlPoints.size(); i++) {
canvas.drawPoint(mControlPoints.get(i).x, mControlPoints.get(i).y, mPaint);
}
}

/**
* 画贝塞尔曲线
*/
private void drawBezier(Canvas canvas) {
mPaint.setStrokeWidth(LINEWIDTH);
mPaint.setColor(LINE_COLOR);
// 重置路径
mPath.reset();
for (int i = 0; i < mPoints.size(); i++) {
if (i == 0) {// 第一条为二阶贝塞尔
mPath.moveTo(mPoints.get(i).x, mPoints.get(i).y);// 起点
mPoints.get(i + 1).x, mPoints.get(i + 1).y);
} else if (i < mPoints.size() - 2) {// 三阶贝塞尔
mPath.cubicTo(mControlPoints.get(2 * i - 1).x, mControlPoints.get(2 * i - 1).y,// 控制点
mControlPoints.get(2 * i).x, mControlPoints.get(2 * i).y,// 控制点
mPoints.get(i + 1).x, mPoints.get(i + 1).y);// 终点
} else if (i == mPoints.size() - 2) {// 最后一条为二阶贝塞尔
mPath.moveTo(mPoints.get(i).x, mPoints.get(i).y);// 起点
mPath.quadTo(mControlPoints.get(mControlPoints.size() - 1).x, mControlPoints.get(mControlPoints.size() - 1).y,
mPoints.get(i + 1).x, mPoints.get(i + 1).y);// 终点
}
}
canvas.drawPath(mPath, mPaint);
}

LinearGradient gradient;//线型渐变色 一把只能在绘制横竖直线 或者矩形图形的时候效果好。
mPaint.setShader(gradient);

Paint p=new Paint();

canvas.drawCicle(0,0,200,mPaint); //参数3为画圆的半径，类型为float型。

LinearGradient shader = new LinearGradient(0, 0, endX, endY, new int[]{startColor, midleColor, endColor},new float[]{0 , 0.5f, 1.0f}, TileMode.MIRROR);

其中参数new float[]{0 , 0.5f, 1.0f}是定义每个颜色处于的渐变相对位置，

这个参数可以为null，如果为null表示所有的颜色按顺序均匀的分布

float x:  圆心X坐标

float y:  圆心Y坐标

int[] colors:  渲染颜色数组

floate[] positions: 相对位置数组,可为null,  若为null,可为null,颜色沿渐变线均匀分布

float x:  圆心X坐标

float y:  圆心Y坐标

int color0: 圆心颜色

int color1: 圆边缘颜色