N阶贝塞尔曲线画法

Posted Leslie X徐

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了N阶贝塞尔曲线画法相关的知识,希望对你有一定的参考价值。

N阶贝塞尔曲线画法

涉及知识:

  • 贝塞尔曲线
  • 牛顿二项式
  • 杨辉三角
  • 组合数

代码:

/**
 * @brief createNBezierCurve 生成N阶贝塞尔曲线点
 * @param src 源贝塞尔控制点
 * @param dest 目的贝塞尔曲线点
 * @param precision 生成精度
 */
static void createNBezierCurve(const QVector<QPointF> &src, QVector<QPointF> &dest, qreal precision)
{

    int size = src.size();

    //系数数组
    QVector<qreal> coff(size,0);

    //准备二维数组a[n][m]表示n阶杨辉三角
    int a[10][10]={{0}};
    {//求系数,个数对应控制点数。使用杨辉三角+组合数的方法
        for(int i=0;i<size;++i)
        {//首尾为 1
            a[i][0]=1;
            a[i][i]=1;
        }
        //利用组合数原理 创建杨辉三角 递推 动态规划法
        for(int i=1;i<size;++i)
            for(int j=1;j<i;++j)
                a[i][j] = a[i-1][j-1] + a[i-1][j];

    }

    //总循环,时间变化 p=t*p1+(1-t)*p0
    for(qreal t1=0; t1<1; t1+=precision ){

        //求每个系数
        qreal t2 = 1 - t1 ;
        int n = size - 1;
        //利用到牛顿二项式展开
        coff[0] = pow(t2,n); coff[n] = pow(t1,n);
        for(int i=1;i<size-1;++i){
            coff[i] = pow(t2,n-i) * pow(t1,i) * a[n][i];
        }

        //求曲线上点
        QPointF ret(0,0);
        for(int i=0;i<size;++i){
            ret += src[i] * coff[i];
        }

        //把所得的点放入目标数组,最后用QPainterPath连起来
        dest.append(ret);
    }

}

使用:

 QVector<QPointF>src{{10,10},{20,30},{40,50},{60,70}};
QVector<QPointF>dest;
createNBezierCurve(src, dest, 0.1);

QPainterPath path;
path.moveTo(dest[0]);
for(int i=1 ;i<dest.size() ;++i){
    path.lineTo(dest[i]);
}

以上是关于N阶贝塞尔曲线画法的主要内容,如果未能解决你的问题,请参考以下文章

贝塞尔曲线 WPF MVVM N阶实现 公式详解+源代码下载

n阶贝塞尔曲线

贝塞尔曲线 WPF MVVM N阶实现 公式详解+源代码下载

用三阶贝塞尔曲线拟合圆

Android UI贝塞尔曲线 ⑦ ( 使用 德卡斯特里奥算法 公式计算的 方法绘制三阶贝塞尔曲线示例 )

Android UI贝塞尔曲线 ① ( 一阶贝塞尔曲线 | 二阶贝塞尔曲线 )