1。这里利用的是三阶贝塞尔曲线,所以需要计算出两个控制点,因为贝塞尔曲线是两点之间的连线,为了保证所有的线段是连接起来是平滑的,所以两个控制点应该取在当前点的切线上,因为切线保证了当前点的一阶导连续。为什么,别问我,问高中老师。所以我的目的是计算出这个切线上的两个控制点。
怎么计算这两个点呢,现在假设这条曲线上有三个点,A为上一个点,B为当前点,C为B后面的点,连接AC,做AC的平行线,切于B,那么控制点1(D)和控制点2(E)就在这条切线(DE)上,然后就是计算D E两点的坐标:目前我也只能理解到这了,然后及时计算公式
算了,直接上公式吧:
preViousX上一个点的X坐标,
currentX 当前点的X坐标
prePreViousX 上上一个点的X坐标
nextY 下一个点的Y坐标
float controlX1= (float) (preViousX+0.25*(currentX-prePreViousX)); float controlY1= (float) (previousY+0.25*(currentY-prePreviousY)); float controlX2 = (float) (currentX -0.25*(nextX-preViousX)); float controlY2 = (float) (currentY - 0.25*(nextY - previousY));
针对两个端点的计算:第一个点,上一个点跟上上一个点的坐标都是当前点, 第二个点,上一个点跟上上一个点的坐标一样,最后一个点,最后一个点的坐标跟当前点一样。
ondraw完全展示:
@Override protected void onDraw (Canvas canvas) { widthSize = getMeasuredWidth(); heightSize = getMeasuredHeight(); String text = "12.34 μSv"; int heightSpace = (heightSize-10-40) / 3; int yHeigiht = heightSize-10-40; float v1 = mTextPaint.measureText(text)+30; for (int i = 0; i < mValues.length; i++) { int y = heightSpace*i+10; if(i==0){ y=20; } if(mValues[i]!=null&&!mValues[i].isEmpty()){ drawTextAndLine(canvas,mValues[i],y); } } int widthSpace = (int) (widthSize-v1-50)/(mWeeks.length-1); mDataPath.reset(); float currentX; float currentY; float preViousX; float previousY; float nextX; float nextY; float prePreViousX; float prePreviousY; for (int i = 0; i < mWeeks.length; i++) { int x = (int) (v1 + widthSpace * i); drawWeekText(canvas,mWeeks[i],x); float y = calculateY(yHeigiht,i); canvas.drawCircle(x,y,10,mCirclePaint); currentX = x; currentY = y; if(i==0){ preViousX = currentX; previousY = currentY; }else{ preViousX = x -widthSpace; previousY = calculateY(yHeigiht,i-1); } if(i>1){ prePreViousX = x - widthSpace*2; prePreviousY = calculateY(yHeigiht,i-2); }else{ prePreViousX = preViousX; prePreviousY = previousY; } if(i==mWeeks.length-1){ nextX = currentX; nextY = currentY; }else{ nextX = currentX +widthSpace; nextY = calculateY(yHeigiht,i+1); } if(i==0){ mDataPath.moveTo(currentX,currentY); }else if(prePreviousY == previousY&&previousY==currentY){ mDataPath.lineTo(currentX,currentY); }else{ float controlX1= (float) (preViousX+0.25*(currentX-prePreViousX)); float controlY1= (float) (previousY+0.25*(currentY-prePreviousY)); float controlX2 = (float) (currentX -0.25*(nextX-preViousX)); float controlY2 = (float) (currentY - 0.25*(nextY - previousY)); mDataPath.cubicTo(controlX1,controlY1,controlX2,controlY2,currentX,currentY); } } canvas.drawPath(mDataPath,mDataPaint); }
我解释的不清,附参考链接:
https://wenku.baidu.com/view/19682071f242336c1eb95e47.html
http://blog.csdn.net/it_zouxiang/article/details/52667896