贝塞尔曲线 多点画

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

 

posted @ 2018-01-24 14:50  贺长寿  阅读(1084)  评论(0编辑  收藏  举报