精华内容
下载资源
问答
  • MATLAB绘制B样条曲线代码,M文件的形式
  • vc++绘制b样条曲线代码

    热门讨论 2013-01-07 21:49:35
    用c++绘制b样条曲线的源代码,适合初学者借鉴学习使用
  • B样条曲线代码实现

    2017-12-24 22:17:01
    使用vs和EasyX对B样条曲线进行代码级实现,并绘制出来
  • B样条曲线

    千次阅读 2015-12-24 15:58:48
    二次B样条曲线代码B样条曲线给定n+m+1n+m+1个平面或空间顶点Pi(i=0,1,…,n+m) P_i (i=0,1,…,n+m),称为nn次参数曲线段: Pk,n(t)=∑i=0nPi+kGi,n(t) , t∈[0,1]P_{k,n}(t)=\sum_{i=0}^nP_{i+k}G_{i,n}(t)\...


    参考文献

    B样条曲线
    二次B样条曲线代码


    B样条曲线

    给定 n+m+1 个平面或空间顶点 Pi(i=01n+m) ,称为 n 次参数曲线段:

    Pk,n(t)=i=0nPi+kGi,n(t) ,    t[0,1]
    为第 k n次B样条曲线段 (k=01m) ,这些曲线段的全体称为 n 次B样条曲线,其顶点Pi(i=01n+m)所组成的多边形称为B样条曲线的特征多边形。 其中,基函数 Gi,n(t) 定义为:

    Gi,n(t)=1n!j=0ni(1)jCjn+1(t+nij)nt[0,1] ,   i=01n


    二次B样条曲线

    n=2 ,则有二次B样条曲线的基函数如下:

    G0,2(t)=12(t1)2G1,2(t)=12(2t2+2t+1)G2,2(t)=12t2

    二次B样条曲线段 P0,2(t)=2i=0PiGi,2(t) 是一段抛物线。二次B样条曲线的矩阵表示为:
    P0,2(t)=12[1tt2]121122001P0P1P2   t[0,1]

    端点位置:
    P0,2(0)=12(P0+P1)P0,2(1)=12(P1+P2)


    代码实现

    #include <stdio.h>
    #include <opencv2\opencv.hpp>
    #include <time.h>
    
    using namespace cv;
    
    void generatePointArray(int * x, int * y, int size, int minX, int maxX, int minY, int maxY) 
    {
        srand((unsigned int) time(0));
        int bandX = maxX - minX;
        int bandY = maxY - minY;
        int i;
        for (i = 0; i < size; i++) {
            x[i] = rand() % bandX + minX;
            y[i] = rand() % bandY + minY;
        }
    }
    
    void drawPointWithLine(Mat & board, int * x, int * y, int size)
    {
        if (size < 1)
            return;
        circle(board, Point(x[0], y[0]), 2, Scalar(255, 0, 0), 1, CV_AA);
        int i;
        for (i = 1; i < size; i++) {
            line(board, Point(x[i-1], y[i-1]), Point(x[i], y[i]), Scalar(0, 255, 0), 1, CV_AA);
            circle(board, Point(x[i], y[i]), 2, Scalar(255, 0, 0), 1, CV_AA);
        }
    }
    
    void BSpline(Mat & board, int * x, int * y, int size) 
    {
        if (size != 3)
            return;
        double t, delta = 1/100.0;
        int px = 0, py = 0;
        for (t = 0; t <= 1.0; t += delta) {
            /*** core code ***/
            double g0 = 0.5*(t - 1)*(t - 1);
            double g1 = 0.5*(-2*t*t + 2*t + 1);
            double g2 = 0.5*t*t;
            int _x = (int) (x[0]*g0 + x[1]*g1 + x[2]*g2);
            int _y = (int) (y[0]*g0 + y[1]*g1 + y[2]*g2);
            /*****************/
    
            if (t == 0)
                circle(board, Point(_x, _y), 2, Scalar(0, 0, 255), 1, CV_AA);
            else
                line(board, Point(px, py), Point(_x, _y), Scalar(0, 128, 255), 1, CV_AA);
            px = _x;
            py = _y;
        }
        if (t != 1.0)
            circle(board, Point((x[1] + x[2]) / 2, (y[1] + y[2]) / 2), 2, Scalar(0, 0, 255), 1, CV_AA);
    }
    
    int main(int argc, char* argv[])
    {
        int boardWidth = 400, boardHeight = 300;
        Mat board = Mat(boardHeight, boardWidth, CV_8UC3);
        memset(board.data, 255, boardHeight*boardWidth*3);
    
        int x[5], y[5];
        generatePointArray(x, y, 5, 0, boardWidth, 0, boardHeight);
    
        drawPointWithLine(board, x, y, 5);
    
        int i;
        for (i = 0; i < 3; i++)
            BSpline(board, x+i, y+i, 3);
    
        imshow("B-Spline", board);
        waitKey(0);
        return 0;
    }
    

    结果1:
    结果1
    结果2:
    结果2

    展开全文
  • B样条曲线的实现代码

    2016-12-06 21:30:15
    该文档中包含了二次、三次B样条曲线的实现方法,可以进行整合调用
  • 三次B样条曲线算法 计算机图形学 MFC 孔令德 代码 课件案例 习题答案 第七章 三次B样条曲线算法 计算机图形学 MFC 孔令德 代码 课件案例 习题答案 第七章
  • B样条曲线VC++MFC代码

    2010-06-03 23:45:44
    计算机图形B样条曲线的MFC代码,包括鼠标响应和菜单函数。。
  • 代码是基于C++的三次B样条曲线拟合代码,包含插值拟合,近似拟合就不放代码了,较简单,我的博客中有相关论文链接。http://blog.csdn.net/liumangmao1314/article/details/54588155
  • B样条曲线逼近

    2018-04-19 17:28:50
    B样条曲线逼近代码,是matlab代码B样条曲线逼近代码,是matlab代码B样条曲线逼近代码,是matlab代码B样条曲线逼近代码,是matlab代码
  • B样条曲线演示程序的代码

    热门讨论 2017-05-13 18:09:58
    一个用纯Qt实现的B样条曲线的演示程序等。详情可以参考我的博客:http://blog.csdn.net/mahabharata_
  • B样条曲线拟合

    2019-01-15 12:07:57
    B样条曲线拟合。实现简单高效,项目中实际使用的代码
  • 三次B样条曲线拟合算法

    万次阅读 多人点赞 2017-01-17 22:10:28
    三次B样条曲线方程B样条曲线分为近似拟合和插值拟合,所谓近似拟合就是不过特征点,而插值拟合就是通过特征点,但是插值拟合需要经过反算得到控制点再拟合出过特征点的B样条曲线方程。这里会一次介绍两种拟合算法。...

    1 三次B样条曲线方程

    B样条曲线分为近似拟合和插值拟合,所谓近似拟合就是不过特征点,而插值拟合就是通过特征点,但是插值拟合需要经过反算得到控制点再拟合出过特征点的B样条曲线方程。这里会一次介绍两种拟合算法。首先介绍B样条的曲线方程。
    B样条曲线的总方程为: P ( t ) = ∑ i = 0 n P i F i , k ( t ) P(t)=\sum_{i=0}^{n} P_{i}F_{i,k}(t) P(t)=i=0nPiFi,k(t) (1)
    其中 P i P_i Pi是控制曲线的特征点, F i , k ( u ) F_{i,k}(u) Fi,k(u)则是K阶B样条基函数。
    1.1 三次B样条曲线方程中基函数为:
    F i , k ( t ) = 1 k ! ∑ m = 0 k − i ( − 1 ) m ( m k + 1 ) ( t + k − m − j ) k F_{i,k}(t)=\frac{1}{k!}\sum_{m=0}^{k-i}(-1)^{m}\binom{m}{k+1}(t+k-m-j)^k Fi,k(t)=k!1m=0ki(1)m(k+1m)(t+kmj)k (2)
    其中 ( m k + 1 ) \binom{m}{k+1} (k+1m)表示阶乘,化成看的明白的式子就是:

    这里写图片描述
    将图片上的基函数代入到方程(1)中,就是:
    P ( t ) = P 0 ∗ F 0 , 3 ( t ) + P 1 ∗ F 1 , 3 ( t ) + P 2 ∗ F 2 , 3 ( t ) + P 3 ∗ F 3 , 3 ( t ) P(t)= P_0*F_{0,3}(t)+P_1*F_{1,3}(t)+P_2*F_{2,3}(t)+P_3*F_{3,3}(t) P(t)=P0F0,3(t)+P1F1,3(t)+P2F2,3(t)+P3F3,3(t) (3)
    方程(3)就是三次B样条曲线方程。


    2019-04-18 更新

    有小伙伴提到上式(2)的j是什么意思,其实j就是控制点的索引值。这里我把书上的公式摘抄下来,可能看起来更为清晰。
    参考书籍:《计算机图形学 第3版》何援军 第13章
    三次B样条曲线计算
    F 0 , 3 ( t ) = 1 3 ! ∑ j = 0 3 ( − 1 ) j C 4 j ) ( t + 3 − 0 − j ) 3 F_{0,3}(t)=\frac{1}{3!}\sum_{j=0}^{3}(-1)^{j}C^{j}_{4})(t+3-0-j)^3 F0,3(t)=3!1j=03(1)jC4j)(t+30j)3

    = 1 6 [ ( − 1 ) 0 C 4 0 ( t + 3 ) 3 + ( − 1 ) 1 C 4 1 ( t + 2 ) 3 + ( − 1 ) 2 C 4 2 ( t + 1 ) 3 + ( − 1 ) 3 C 4 3 t 3 ] =\frac{1}{6}[(-1)^{0}C^{0}_{4}(t+3)^{3}+(-1)^{1}C^{1}_{4}(t+2)^{3}+(-1)^{2} C^{2}_{4}(t+1)^{3}+(-1)^{3}C^{3}_{4}t^{3}] =61[(1)0C40(t+3)3+(1)1C41(t+2)3+(1)2C42(t+1)3+(1)3C43t3]

    = 1 6 ( − t 3 + 3 t 2 − 3 t + 1 ) = 1 6 ( 1 − t ) 3 =\frac{1}{6}(-t^{3}+3t^{2}-3t+1)=\frac{1}{6}(1-t)^{3} =61(t3+3t23t+1)=61(1t)3

    F 1 , 3 ( t ) = 1 3 ! ∑ j = 0 2 ( − 1 ) j C 4 j ) ( t + 3 − 1 − j ) 3 F_{1,3}(t)=\frac{1}{3!}\sum_{j=0}^{2}(-1)^{j}C^{j}_{4})(t+3-1-j)^3 F1,3(t)=3!1j=02(1)jC4j)(t+31j)3

    = 1 6 [ ( − 1 ) 0 C 4 0 ( t + 2 ) 3 + ( − 1 ) 1 C 4 1 ( t + 1 ) 3 + ( − 1 ) 2 C 4 2 t 3 ] =\frac{1}{6}[(-1)^{0}C^{0}_{4}(t+2)^{3}+(-1)^{1}C^{1}_{4}(t+1)^{3}+(-1)^{2} C^{2}_{4}t^{3}] =61[(1)0C40(t+2)3+(1)1C41(t+1)3+(1)2C42t3]

    = 1 6 ( 3 t 3 − 6 t 2 + 4 ) =\frac{1}{6}(3t^{3}-6t^{2}+4) =61(3t36t2+4)

    F 2 , 3 ( t ) = 1 3 ! ∑ j = 0 1 ( − 1 ) j C 4 j ) ( t + 3 − 2 − j ) 3 F_{2,3}(t)=\frac{1}{3!}\sum_{j=0}^{1}(-1)^{j}C^{j}_{4})(t+3-2-j)^3 F2,3(t)=3!1j=01(1)jC4j)(t+32j)3

    = 1 6 [ ( − 1 ) 0 C 4 0 ( t + 1 ) 3 + ( − 1 ) 1 C 4 1 t 3 =\frac{1}{6}[(-1)^{0}C^{0}_{4}(t+1)^{3}+(-1)^{1}C^{1}_{4}t^{3} =61[(1)0C40(t+1)3+(1)1C41t3

    = 1 6 ( − 3 t 3 + 3 t 2 + 3 t + 1 ) =\frac{1}{6}(-3t^{3}+3t^{2}+3t+1) =61(3t3+3t2+3t+1)

    F 3 , 3 ( t ) = 1 3 ! ∑ j = 0 0 ( − 1 ) j C 4 j ) ( t + 3 − 3 − j ) 3 F_{3,3}(t)=\frac{1}{3!}\sum_{j=0}^{0}(-1)^{j}C^{j}_{4})(t+3-3-j)^3 F3,3(t)=3!1j=00(1)jC4j)(t+33j)3

    = 1 6 [ ( − 1 ) 0 C 4 0 t 3 =\frac{1}{6}[(-1)^{0}C^{0}_{4}t^{3} =61[(1)0C40t3

    = 1 6 t 3 =\frac{1}{6}t^{3} =61t3


    2 三次B样条曲线近似拟合

    近似拟合很简单。不需要求控制点,求得 F i , k ( t ) F_{i,k}(t) Fi,k(t),由上述方程(3),代入 P 0 , P 1 , P 2 , P 3 P_0,P_1,P_2,P_3 P0,P1,P2,P3就可以得到由这四个点近似拟合的一段三次B样条曲线,起始点在 P 0 P_0 P0,终点在 P 1 P_1 P1,对于闭合轮廓,最后一段可以取前两点做辅助,拟合实验结果我最后一块给出。这种近似拟合曲线光滑,但是最大不足就是不过特征点,也就是不过 P i P_i Pi,需要过点需要反求控制点再拟合。

    3 三次B样条插值拟合

    插值拟合较为复杂。其实也不算是很复杂,找资料过程和理解过程是一个复杂的过程。不过有了前面大神做工作,我们只是借用别人的成果写代码就好了。我给大家看一篇论文,大家可以百度或者去知网搜索,闭合 B 样条曲线控制点的快速求解算法及应用。文章讲解了反求控制点的具体步骤,写的非常详细,基本上贴近代码的那种。大家可以根据这篇论文反求控制点,拟合出来的三次B样条曲线是经过 P i P_i Pi的。代码就不放了,很多,可以根据我给的那篇论文直接编写相应代码,有问题可以私信我,知无不言。
    ##4 拟合结果
    这里写图片描述 原轮廓
    这里写图片描述 近似拟合轮廓。可以看到没过黑色特征点,只是近似拟合
    这里写图片描述 插值拟。可以看到曲线经过黑色特征点,不过有一些不足之处。

    ##5 总结
    三次B样条曲线拟合轮廓效果还是可以,较之Beizer(可以参考我博客三次Beizer曲线拟合算法),B样条将一些细节描述的很好,很多细节之处都贴近原轮廓,但是有一些不足之处,可以看到对直线拟合效果不是很好。两篇博客都是关于闭合轮廓的拟合,对于非闭合或者只是一段曲线拟合,还有一种曲线是很好的,《数值分析》提到过,叫三次样条插值拟合,拟合效果很好,我做过拟合一元三次方程曲线,拟合效果跟原曲线非常贴近,不过过程中需要用到追赶法,而追赶法需要满足一个条件,对于闭合曲线三次样条插值是不满足这个条件的,所以我没去深研究,大家可以去试一试。谢谢大家!

    -------------------------------------------------2018-10-30--------------------------------------------
    真的很感谢大家的支持,这一年都比较忙,找实习and找工作,而且这个东西是研一上学期搞的,现在看都毫无印象,对自己说一句:牛逼。我把代码放在网盘了(能运行,但现在没效果,大家可以检查下,之前是OK的),本来想上传到CSDN,好像要C币,而且要审核,太墨迹了。
    链接: https://pan.baidu.com/s/1mSQMmvL71gwEAqgiT6O9Gg 提取码: xv5f

    展开全文
  • 亲测好用 一个用纯Qt实现的B样条曲线的演示程序等。详情可以参考我的博客:http://blog.csdn.net/mahabharata_
  • B样条曲线原理

    2014-02-24 16:02:02
    B样条曲线几何原理演示,里面有源代码,是c++的,欢迎下载
  • B样条曲线演示程序

    2017-05-13 18:59:17
    这是一个用Qt实现的B样条曲线的演示程序,源代码的下载链接在我的博客或者我的其他下载资源中可以找到:
  • B样条曲线生成原理及实现

    热门讨论 2011-11-03 08:55:20
    B样条曲线的概念和定义出发,按节点矢量中节点的 分布情况把B样条曲线划分成均匀B样条曲线、准均匀B样条...类型,分别对它们的特点和实现方法进行了详细阐述,最后给出了一个完整的各种B样条曲线生成代码和运行结 果
  • MATLAB绘制B样条曲线

    万次阅读 多人点赞 2015-05-09 18:50:42
    1 B样条曲线1.1 B样条曲线定义B样条方法具有表示与设计自由型曲线曲面的强大功能,是形状数学描述的主流方法之一,另外B样条方法是目前工业产品几何定义国际标准——有理B样条方法(NURBS)的基础。B样条方法兼备了...

    1 B样条曲线

    1.1 B样条曲线定义

    B样条方法具有表示与设计自由型曲线曲面的强大功能,是形状数学描述的主流方法之一,另外B样条方法是目前工业产品几何定义国际标准——有理B样条方法(NURBS)的基础。B样条方法兼备了Bezier方法的一切优点,包括几何不变性,仿射不变性等等,同时克服了Bezier方法中由于整体表示带来不具有局部性质的缺点(移动一个控制顶点将会影响整个曲线)。B样条曲线方程可写为:

    p(u)=i=0ndiNi,k(u)

    其中, di(i=0,1...n) 为控制顶点(坐标), Ni,k(i=0,1...n) k 次规范B样条基函数,最高次数是k。基函数是由一个称为节点矢量的非递减参数 u 的序列U u0u1...un+k+1 所决定的 k 次分段多项式。
    B样条的基函数通常采用Cox-deBoor递推公式:
    Ni,0(u)={1,  if  uiuui+10,  othersNi,k=uuiui+kuiNi,k1(u)+ui+k+1uui+k+1ui+1Ni+1,k1(u)define  00=0

    式中 i 为节点序号, k 是基函数的次数,共有 n+1 个控制顶点。 注意区分节点和控制顶点,节点是在节点矢量 U 中取得,控制顶点则是坐标点,决定B样条的控制多边形。Cox-deBoor递推公式是B样条曲线的定义的核心,该部分在程序中实现可采用递归的方式:

    % BaseFunction.m文件
    function Nik_u = BaseFunction(i, k , u, NodeVector)
    % 计算基函数Ni,k(u),NodeVector为节点向量
    
    if k == 0       % 0次B样条
        if (u >= NodeVector(i+1)) && (u < NodeVector(i+2))
            Nik_u = 1.0;
        else
            Nik_u = 0.0;
        end
    else
        Length1 = NodeVector(i+k+1) - NodeVector(i+1);
        Length2 = NodeVector(i+k+2) - NodeVector(i+2);      % 支撑区间的长度
        if Length1 == 0.0       % 规定0/0 = 0
            Length1 = 1.0;
        end
        if Length2 == 0.0
            Length2 = 1.0;
        end
        Nik_u = (u - NodeVector(i+1)) / Length1 * BaseFunction(i, k-1, u, NodeVector) ...
            + (NodeVector(i+k+2) - u) / Length2 * BaseFunction(i+1, k-1, u, NodeVector);
    end

    所给程序可用于计算基函数Ni,k(u)的值,程序中对不同类型的B样条曲线区别在于节点矢量 NodeVector 的取值不同。

    1.2 B样条曲线的分类

    根据节点矢量中节点的分布情况不同,可以划分4中类型的B样条曲线:
    1. 均匀B样条曲线
    节点矢量中节点为沿参数轴均匀或等距分布。
    2. 准均匀B样条曲线
    其节点矢量中两端节点具有重复度 k+1 ,即 u0=u1=...=uk un+1=un+2=...=un+k+1 ,所有的内节点均匀分布,具有重复度1。
    3. 分段Bezier曲线
    其节点矢量中两端节点的重复度与类型2相同,为 k+1 。不同的是内节点重复度为 k 。该类型有限制条件,控制顶点数减1必须等于次数的正整数倍,即nk=
    4. 一般非均匀B样条曲线
    对任意分布的节点矢量 U=[u0,u1...un+k+1] ,只要在数学上成立都可选取。

    2 B样条曲线的绘制

    2.1 节点矢量的确定

    不同类型的B样条曲线区别主要在于节点矢量,对于具有 n+1 个控制顶点 (P0,P1,...,Pn) k 次B样条曲线,无论是哪种类型都具有n+k+2个节点 ([u0,u1...un+k+1])

    $n=4,k=2时不同类型的节点矢量$

    根据图示,三种类型的B样条曲线对应的节点矢量分别为:

    [01727374757671]
    [0 0 013231 1 1]
    [0 0 012121 1 1]
    需要注意的是分段Bezier曲线必须满足 nk=

    这里给出准均匀B样条和分段Bezier曲线的生成节点矢量的代码,均匀B样条的很简单就不列出了。假设共n+1个控制顶点,k次B样条,输入参数为 n, k ,输出节点矢量NodeVector。


    准均匀B样条曲线的节点矢量生成:

    % U_quasi_uniform.m文件
    function NodeVector = U_quasi_uniform(n, k)
    % 准均匀B样条的节点向量计算,共n+1个控制顶点,k次B样条
    NodeVector = zeros(1, n+k+2);
    piecewise = n - k + 1;       % 曲线的段数
    if piecewise == 1       % 只有一段曲线时,n = k
        for i = n+2 : n+k+2
            NodeVector(1, i) = 1;
        end
    else
        flag = 1;       % 不止一段曲线时
        while flag ~= piecewise
            NodeVector(1, k+1+flag) = NodeVector(1, k + flag) + 1/piecewise;
            flag = flag + 1;
        end
        NodeVector(1, n+2 : n+k+2) = 1;
    end

    分段Bezier曲线的节点矢量生成:

    % U_piecewise_Bezier.m文件
    function NodeVector = U_piecewise_Bezier(n, k)
    % 分段Bezier曲线的节点向量计算,共n+1个控制顶点,k次B样条
    % 分段Bezier端节点重复度为k+1,内间节点重复度为k,且满足n/k为正整数
    
    if ~mod(n, k) && (~mod(k, 1) && k>=1)   % 满足n是k的整数倍且k为正整数
        NodeVector = zeros(1, n+k+2);   % 节点矢量长度为n+k+2
        NodeVector(1, n+2 : n+k+2) = ones(1, k+1);  % 右端节点置1
    
        piecewise = n / k;      % 设定内节点的值
        Flg = 0;
        if piecewise > 1
            for i = 2 : piecewise
                for j = 1 : k
                    NodeVector(1, k+1 + Flg*k+j) = (i-1)/piecewise;
                end
                Flg = Flg + 1;
            end
        end
    
    else
        fprintf('error!\n');
    end

    2.2 B样条曲线的绘制

    根据B样条曲线的定义公式,曲线上任一点坐标值是参数变量 u 的函数,用矩阵形式表示

    p(u)=(d0d1dn)N0,k(u)N1,k(u)Nn,k(u)
    只需要确定控制顶点 di 、曲线的次数 k 以及基函数Ni,k(u),就完全确定了曲线。


    B样条曲线的绘制函数:

    % DrawSpline.m文件
    function DrawSpline(n, k, P, NodeVector)
    % B样条的绘图函数
    % 已知n+1个控制顶点P(i), k次B样条,P是2*(n+1)矩阵存控制顶点坐标, 节点向量NodeVector
    plot(P(1, 1:n+1), P(2, 1:n+1),...
                        'o','LineWidth',1,...
                        'MarkerEdgeColor','k',...
                        'MarkerFaceColor','g',...
                        'MarkerSize',6);
    line(P(1, 1:n+1), P(2, 1:n+1));
    Nik = zeros(n+1, 1);
    for u = 0 : 0.005 : 1-0.005
        for i = 0 : 1 : n
            Nik(i+1, 1) = BaseFunction(i, k , u, NodeVector);
        end
        p_u = P * Nik;
        if u == 0
            tempx = p_u(1,1);
            tempy = p_u(2,1);
            line([tempx p_u(1,1)], [tempy p_u(2,1)],...
                'Marker','.','LineStyle','-', 'Color',[.3 .6 .9], 'LineWidth',3);
        else
            line([tempx p_u(1,1)], [tempy p_u(2,1)],...
                'Marker','.','LineStyle','-', 'Color',[.3 .6 .9], 'LineWidth',3);
            tempx = p_u(1,1);
            tempy = p_u(2,1);
        end
    end

    调用 DrawSpline(n, k, P, NodeVector) 函数就能绘制曲线,注意输入变量要正确。


    下面给出绘制三种不同B样条曲线的命令流,可以参考比较每种类型之间的区别。

    % 绘制三种类型的B样条曲线,需要前面所给的所有.m文件
    clear all;
    %控制顶点
    P = [9.036145, 21.084337, 37.607573, 51.893287, 61.187608;
        51.779661, 70.084746, 50.254237, 69.745763, 49.576271];
    
    n = 4; k = 2;
    
    flag = 2;
    % flag = 1,绘制均匀B样条曲线
    % flag = 2, 绘制准均匀B样条曲线
    % flag = 3, 绘制分段Bezier曲线
    
    switch flag
        case 1
            NodeVector = linspace(0, 1, n+k+2); % 均匀B样条的节点矢量
    
            % 绘制样条曲线
            plot(P(1, 1:n+1), P(2, 1:n+1),...
                            'o','LineWidth',1,...
                            'MarkerEdgeColor','k',...
                            'MarkerFaceColor','g',...
                            'MarkerSize',6);
            line(P(1, 1:n+1), P(2, 1:n+1));
            Nik = zeros(n+1, 1);
            for u = k/(n+k+1) : 0.001 : (n+1)/(n+k+1)
                % for u = 0 : 0.005 : 1
                for i = 0 : 1 : n
                    Nik(i+1, 1) = BaseFunction(i, k , u, NodeVector);
                end
            p_u = P * Nik;
            line(p_u(1,1), p_u(2,1), 'Marker','.','LineStyle','-', 'Color',[.3 .6 .9]);
            end
        case 2
            NodeVector = U_quasi_uniform(n, k); % 准均匀B样条的节点矢量
            DrawSpline(n, k, P, NodeVector);
        case 3
            NodeVector = U_piecewise_Bezier(n, k);  % 分段Bezier曲线的节点矢量
            DrawSpline(n, k, P, NodeVector);
        otherwise
            fprintf('error!\n');
    end

    三种类型的B样条曲线:
    1. 均匀B样条曲线
    均匀B样条曲线
    2. 准均匀B样条曲线
    准均匀B样条曲线
    3. 分段Bezier曲线
    分段Bezier曲线

    参考文献:

    [1] 施法中. 计算机辅助几何设计与非均匀有理B样条(修订版)[M]. 北京: 高等教育出版社, 2013 : 217-248.

    展开全文
  • B样条曲线绘制猫

    2014-05-21 17:14:11
    B样条曲线绘制猫,代码简单易懂,使用win32 application,没有MFC的复杂类定义
  • B样条曲线曲面(附代码

    千次阅读 2016-05-01 23:34:00
    1 B样条曲线 1.1 B样条曲线方程 B样条方法具有表示与设计自由型曲线曲面的强大功能,是形状数学描述的主流方法之一,另外B样条方法是目前工业产品几何定义国际标准——有理B样条方法 (NURBS)的基础。B样条方法兼备...

    1 B样条曲线

    1.1 B样条曲线方程

    B样条方法具有表示与设计自由型曲线曲面的强大功能,是形状数学描述的主流方法之一,另外B样条方法是目前工业产品几何定义国际标准——有理B样条方法 (NURBS)的基础。B样条方法兼备了Bezier方法的一切优点,包括几何不变性,仿射不变性等等,同时克服了Bezier方法中由于整体表示带来不具有局部性质的缺点(移动一个控制顶点将会影响整个曲线)。B样条曲线方程可表示为

    clip_image002[4]

    其中,di(i=0,1...n)为控制顶点(坐标),Ni,k(i=0,1...n)k次规范B样条基函数,最高次数是k。基函数是由一个称为节点矢量的非递减参数u的序列Uu0u1≤...≤un+k+1所决定的k次分段多项式。

    B样条的基函数通常采用Cox-deBoor递推公式:

    clip_image004[14]    (2)

     

    式中i为节点序号,k是基函数的次数,共有n+1个控制顶点。注意区分节点和控制顶点,节点是在节点矢量U中取得,控制顶点则是坐标点,决定B样条的控制多边形Cox-deBoor递推公式是B样条曲线的定义的核心,该公式在程序中的实现可采用递归的方式:

     1 function Nik_u = BaseFunction(i, k , u, NodeVector)
     2 % 计算基函数Ni,k(u),NodeVector为节点向量
     3 
     4 if k == 0       % 0次B样条
     5     if (u >= NodeVector(i+1)) && (u < NodeVector(i+2))
     6         Nik_u = 1.0;
     7     else
     8         Nik_u = 0.0;
     9     end
    10 else
    11     Length1 = NodeVector(i+k+1) - NodeVector(i+1);
    12     Length2 = NodeVector(i+k+2) - NodeVector(i+2);      % 支撑区间的长度
    13     if Length1 == 0.0       % 规定0/0 = 0
    14         Length1 = 1.0;
    15     end
    16     if Length2 == 0.0
    17         Length2 = 1.0;
    18     end
    19     Nik_u = (u - NodeVector(i+1)) / Length1 * BaseFunction(i, k-1, u, NodeVector) ...
    20         + (NodeVector(i+k+2) - u) / Length2 * BaseFunction(i+1, k-1, u, NodeVector);
    21 end
    Cox-deBoor递推公式

    所给程序可用于计算基函数Ni,k(u)的值,程序中对不同类型的B样条曲线区别在于节点矢量 NodeVector 的取值不同。

     

    1.2 B样条曲线的分类

    根据节点矢量中节点的分布情况不同,可以划分4中类型的B样条曲线。不同类型的B样条曲线区别主要在于节点矢量,对于具有n+1个控制顶点clip_image006[9] k B样条曲线,无论是哪种类型都具有n+k+2个节点clip_image008[4]

    clip_image010[4]

    均匀B样条曲线

    节点矢量中节点为沿参数轴均匀或等距分布。

    对应的节点矢量:clip_image012[4]

    clip_image016[4]

     

    准均匀B样条曲线

    其节点矢量中两端节点具有重复度k+1,即u0=u1=...=ukun+1=un+2=...=un+k+1,所有的内节点均匀分布,具有重复度1

    对应的节点矢量:clip_image018[4]

    clip_image022[4]

     

    分段Bezier曲线

    其节点矢量中两端节点的重复度与类型2相同,为k+1。不同的是内节点重复度为k。该类型有限制条件,控制顶点数减1必须等于次数的正整数倍,即必须满足clip_image024[4] 正整数。

    对应的节点矢量:clip_image026[4]

    clip_image030[4]

     

    一般非均匀B样条曲线

    对任意分布的节点矢量clip_image032[4],只要在数学上成立都可选取。

     

    这里给出准均匀B样条和分段Bezier曲线的生成节点矢量的代码,均匀B样条的很简单就不列出了。假设共n+1个控制顶点,kB样条,输入参数为 n, k ,输出节点矢量到NodeVector中。

     

     1 function NodeVector = U_quasi_uniform(n, k)
     2 % 准均匀B样条的节点向量计算,共n+1个控制顶点,k次B样条
     3 NodeVector = zeros(1, n+k+2);
     4 piecewise = n - k + 1;       % 曲线的段数
     5 if piecewise == 1       % 只有一段曲线时,n = k
     6     for i = n+2 : n+k+2
     7         NodeVector(1, i) = 1;
     8     end
     9 else
    10     flag = 1;       % 不止一段曲线时
    11     while flag ~= piecewise
    12         NodeVector(1, k+1+flag) = NodeVector(1, k + flag) + 1/piecewise;
    13         flag = flag + 1;
    14     end
    15     NodeVector(1, n+2 : n+k+2) = 1;
    16 end
    准均匀B样条节点向量

     

     1 function NodeVector = U_piecewise_Bezier(n, k)
     2 % 分段Bezier曲线的节点向量计算,共n+1个控制顶点,k次B样条
     3 % 分段Bezier端节点重复度为k+1,内间节点重复度为k,且满足n/k为正整数
     4 
     5 if ~mod(n, k) && (~mod(k, 1) && k>=1)   % 满足n是k的整数倍且k为正整数
     6     NodeVector = zeros(1, n+k+2);   % 节点矢量长度为n+k+2
     7     NodeVector(1, n+2 : n+k+2) = ones(1, k+1);  % 右端节点置1
     8     
     9     piecewise = n / k;      % 设定内节点的值
    10     Flg = 0;
    11     if piecewise > 1
    12         for i = 2 : piecewise
    13             for j = 1 : k
    14                 NodeVector(1, k+1 + Flg*k+j) = (i-1)/piecewise;
    15             end
    16             Flg = Flg + 1;
    17         end
    18     end
    19     
    20 else
    21     fprintf('error!\n');
    22 end
    分段Bezier曲线的节点向量

     

    1.3 B样条曲线的计算

    根据B样条曲线的定义公式(1),曲线上任一点坐标值是参数变量u的函数,用矩阵形式表示

    clip_image034[4]     (3)

     

    可以看出只要已知控制顶点坐标clip_image036[4]、曲线的次数clip_image038[4] 以及基函数clip_image040[4],就完全确定了B样条曲线,其中基函数clip_image042[4]Cox-deBoor 公式(2)递推计算。

     

    2 B样条曲面

    2.1 B样条曲面方程

    确定一张clip_image044[6]次张量积B样条曲面需要三个信息:

    •   给定clip_image046[4]个控制顶点clip_image048[4]构成控制网格
    •   给定参数clip_image050[4]clip_image052[4]的次数clip_image054[4]clip_image056[4]
    •       u向和v向的节点矢量clip_image058[4]clip_image060[4]

    clip_image062[4]

    定义的clip_image044[7]次张量积B样条曲面其方程为:

    clip_image064[4]

    clip_image066[4]B样条基clip_image068[4]clip_image070[4]分别由节点矢量clip_image072[4]clip_image074[4]Cox-deBoor递推公式(2)计算。

    B样条曲面按照沿参数方向u, v所取的节点矢量不同,也可以划分成不同的类型:均匀、准均匀、分片Bezier和非均匀B样条曲面。

    2.2 B样条曲面的计算

      给定曲面的控制顶点并确定次数后,还需要根据不同类型的B样条曲面沿参数方向的节点矢量才能完全定义一张B样条曲面。要计算B样条曲面上的顶点坐标,首先沿一个参数方向如u向或v向,计算出该方向由控制顶点确定的B样条曲线,如下图中的红色曲线是沿u向生成的二次均匀B样条曲线,一共有四条。

    clip_image076[4]

    之后将沿u向计算得到的B样条曲线上的点作为新的控制顶点,得到张量网格沿v向计算,得到的曲线就是B样条曲面上的,下图中绿色线段组成的就是沿v向的控制的顶点,蓝颜色的曲线是沿v向的二次均匀B样条曲线构成了一张二次均匀B样条曲面。关于B样条曲面实现的代码这里可以下载。

    clip_image078[4]clip_image080[4]clip_image082[4]

    参考文献:

    [1] 施法中. 计算机辅助几何设计与非均匀有理B样条(修订版)[M]. 北京: 高等教育出版社, 2013.

     

    转载于:https://www.cnblogs.com/nobodyzhou/p/5451528.html

    展开全文
  • 实现C++ opengl的glut库接口函数画贝塞尔曲线和均匀B样条曲线
  • 收集的Bezier,B样条曲线正算,返算代码及文档说明
  • B样条曲线的插值python代码

    千次阅读 2020-05-13 14:46:33
    由于毕业设计的需要,生成的刀位点,个人觉得间隔有点大,为了能够以后用于实际加工,因此花了一上午的时间稍微了解了一下B样条曲线,废话不多说,直接上代码 import matplotlib as mpl import matplotlib.pyplot as...
  • 简单详细的均匀三次B样条曲线插值MATLAB代码,有注释
  • 对多个点组成的数组进行插值拟合,在折点处得到光滑的曲线
  • 基于B样条曲线的路径规划(含matlab代码

    千次阅读 多人点赞 2020-05-26 22:48:17
    本文主要解决的是用B样条曲线实现无人车的路径规划,对于B样条曲线的概念不再赘述,有兴趣的朋友可以自行去了解。 下面介绍如何利用B样条曲线对小车进行路径规划。 1.无人车平面曲线规划 1.1无人车位置控制 我们...
  • % ref: 闭合 B 样条曲线控制点的快速求解算法及应用 % http://www.doc88.com/p-5714423317458.html % https://blog.csdn.net/liumangmao1314/article/details/54588155 ========================...

空空如也

空空如也

1 2 3 4 5 ... 20