精华内容
下载资源
问答
  • B样条曲线曲面

    2011-09-16 16:09:00
    B样条曲线曲面B样条曲线曲面, 介绍了原理以及实现方法等,对研究游戏很有帮助
  • B样条曲线曲面和NURBS曲线曲面C语言算法源程序》由会员分享,可在线阅读,更多相关《B样条曲线曲面和NURBS曲线曲面C语言算法源程序(27页珍藏版)》请在人人文库网上搜索。1、学习小结:前面学习了Bezier曲线,B样条...

    《B样条曲线曲面和NURBS曲线曲面C语言算法源程序》由会员分享,可在线阅读,更多相关《B样条曲线曲面和NURBS曲线曲面C语言算法源程序(27页珍藏版)》请在人人文库网上搜索。

    1、学习小结:前面学习了Bezier曲线,B样条基函数和B样条曲线的一些基础知识。掌握关键问题是一条B样条曲线间的多段曲线的光滑连接。因为现在是用多段Bezier曲线来描绘一条B样条曲线,所以问题变为两段Bezier曲线间光滑连接。两段Bezier曲线段(3次)B1和B2光滑连接的条件:(1).要求B1和B2有共同的连接点,即G0连续。(2).要求B1和B2在连接点处有成比例的一阶导数,即G1连续。由端点处的一阶导数,为实现G1连续,则有:即: 这也表明,三点共线。如下图表示了一条3次B样条曲线的所有控制多边形:(P1) P2 P3P4 (P11) (P12)P5 P10P0 P6 P9P7 P8。

    2、 图5.3次B样条曲线和所有控制多边形 图5中,P0至P6为原始3次B样条曲线控制多边形顶点,P0至P12是计算后最终形成B样条曲线控制多边形顶点。图6.双二次(2x2)B样条曲面6.B样条曲线曲面和NURBS曲线曲面的C语言实现算法源程序#ifndef _mynurbs_h#ifndef _MYNURBS_H#include glgl.h#include math.h/*-*-*-*-*-*-*-*-*-*-*-*-*-*-* B样条基函数计算部分 *-*-*-*-*-*-*-*-*-*-*-*-*-*/确定参数u所在的节点区间下标/n=m-p-1 /m为节点矢量U的最大下标/p为B样条函数。

    3、次数int FindSource(int n,int p,float u,float U)int low,high,mid;if(u=Un+1)/特殊情况return n;/进行二分搜索low=p;high=n+1;mid=(int)(low+high)/2;while(uUmid)if(u=Umid&u=i-k;di-)if(u=Udi&u2void DerBasisFunc(int i,int p,float u,float U,float NP)int j,di,dp,k;float tul,tur,left,right,saved,dl,dr;float tmpN5050;for(k=。

    4、0;k=i-k;di-)if(u=Udi&u0&i=i-p;j-)tmp+=Nj*Pj;Deri-p=tmp;/计算曲线上的点(u所对应的所有点)保存在Poi中/n=m-p-1/p为曲线的次数void BSplinePoint(int n,int p,float U,float P,float Poi)float N100,tmp;int i,j;for(i=p+1;i=i-p;j-)tmp+=Nj*Pj;Poii-p=tmp;/计算3次样条曲线上的所有控制多边形保存在CP中/m为节点矢量U的最大下标void B3SplineControlPoint(int m,float U,float P。

    5、,float CP)int n,k,i,cp,p;float Poi100,Der100,add;p=3;n=m-p-1;BSplinePoint(n,p,U,P,Poi);BSplineDer(n,p,U,P,Der);cp=(n-p)*3+p;for(i=0;i=i-p;j-)tmp+=Nj*Pj*Wj;tmw+=Nj*Wj;Poii-p=tmp/tmw;/计算Nurbs曲线的1阶导矢(u所对应的所有点)保存在Der中/n=m-p-1/p为曲线的次数void NurbsDer(int n,int p,float U,float P,float W,float Der)float N100,。

    6、CP100,NW100,tmp,tw;int i,j;NurbsPoint(n,p,U,P,W,CP);BSplinePoint(n,p,U,W,NW);for(i=p+1;i=i-p;j-)tmp+=Nj*Pj*Wj;tw+=Nj*Wj;Deri-p=(tmp-tw*CPi-p)/NWi-p;/计算3次Nurbs曲线上的所有控制多边形保存在CP中/m为节点矢量U的最大下标void Nurbs3ControlPoint(int m,float U,float P,float W,float CP)int n,k,i,cp,p;float Poi100,Der100,add;p=3;n=m-p-。

    7、1;NurbsPoint(n,p,U,P,W,Poi);NurbsDer(n,p,U,P,W,Der);cp=(n-p)*3+p;for(i=0;i2;i+)CPi=Pi;CPcp-i=Pn-i;for(i=3;icp-1;i+=3) k=(int)i/3;add=Derk/p;CPi=Poik;CPi-1=CPi-add;CPi+1=CPi+add;/计算2次Nurbs曲线上的所有控制多边形保存在CP中/m为节点矢量U的最大下标void Nurbs2ControlPoint(int m,float U,float P,float W,float CP)int n,k,tm,i,cp,p;fl。

    8、oat Poi100;p=2;n=m-p-1;NurbsPoint(n,p,U,P,W,Poi);cp=(n-p)*2+p;for(i=0;i2;i+)CPi=Pi;CPcp=Pn;tm=2;for(i=2;icp-1;i+=2) k=(int)i/2;CPi=Poik;CPi+1=Ptm;tm+;/绘制3次Nurbs样条曲线/m为节点矢量U的最大下标void Nurbs3L(int m,float U,float px,float py,float pz,float W)float pcx100,pcy100,pcz100,drx4,dry4,drz4;float pcw100,drw4;i。

    9、nt i,j,tmcp;Nurbs3ControlPoint(m,U,px,W,pcx);Nurbs3ControlPoint(m,U,py,W,pcy);Nurbs3ControlPoint(m,U,pz,W,pcz);B3SplineControlPoint(m,U,W,pcw);tmcp=m-7;for(i=0;i=tmcp;i+)for(j=i*3;ji*3+4;j+)drxj-i*3=pcxj;dryj-i*3=pcyj;drzj-i*3=pczj;drwj-i*3=pcwj;NBezier(3,drx,dry,drz,drw,20);/绘制2次Nurbs样条曲线/m为节点矢量U的最。

    10、大下标void Nurbs2L(int m,float U,float px,float py,float pz,float W)float pcx100,pcy100,pcz100,drx3,dry3,drz3;float pcw100,drw3;int i,j,tmcp;Nurbs2ControlPoint(m,U,px,W,pcx);Nurbs2ControlPoint(m,U,py,W,pcy);Nurbs2ControlPoint(m,U,pz,W,pcz);B2SplineControlPoint(m,U,W,pcw);tmcp=m-5;for(i=0;i=tmcp;i+)for(。

    11、j=i*2;ji*2+3;j+)drxj-i*2=pcxj;dryj-i*2=pcyj;drzj-i*2=pczj;drwj-i*2=pcwj;NBezier(2,drx,dry,drz,drw,20);/计算双三次(3x3)Nurbs样条曲面所有控制多边形顶点,并保存在pt中/mu,mv分别为节点矢量U,V的最大下标值void Nurbs3FControlPoint(int mu,float U,int mv,float V,float px,float py,float pz,float W,float pt1001004)int i,j,k,dp;float tmx50,tmy50,tm。

    12、z50,tmw50;float tmpx50100,tmpy50100,tmpz50100,tmpw50100;float uvx100100,uvy100100,uvz100100,uvw100100;for(i=0;imv-3;i+)dp=i*(mu-3);for(j=dp;jmu-3+dp;j+)tmxj-dp=pxj;tmyj-dp=pyj;tmzj-dp=pzj;tmwj-dp=Wj;Nurbs3ControlPoint(mu,U,tmx,tmw,tmpxi);Nurbs3ControlPoint(mu,U,tmy,tmw,tmpyi);Nurbs3ControlPoint(mu,U。

    13、,tmz,tmw,tmpzi);B3SplineControlPoint(mu,U,tmw,tmpwi);for(i=0;i3*mu-17;i+)for(j=0;jmv-3;j+)tmxj=tmpxji;tmyj=tmpyji;tmzj=tmpzji;tmwj=tmpwji;Nurbs3ControlPoint(mv,V,tmx,tmw,uvxi);Nurbs3ControlPoint(mv,V,tmy,tmw,uvyi);Nurbs3ControlPoint(mv,V,tmz,tmw,uvzi);B3SplineControlPoint(mv,V,tmw,uvwi);for(k=0;k3*m。

    14、v-17;k+)ptik0=uvxik;ptik1=uvyik;ptik2=uvzik;ptik3=uvwik;/计算双二次(2x2)Nurbs样条曲面所有控制多边形顶点,并保存在pt中/mu,mv分别为节点矢量U,V的最大下标值void Nurbs2FControlPoint(int mu,float U,int mv,float V,float px,float py,float pz,float W,float pt1001004)int i,j,k,dp;float tmx50,tmy50,tmz50,tmw50;float tmpx50100,tmpy50100,tmpz50100,。

    15、tmpw50100;float uvx100100,uvy100100,uvz100100,uvw100100;for(i=0;imv-2;i+)dp=i*(mu-2);for(j=dp;jmu-2+dp;j+)tmxj-dp=pxj;tmyj-dp=pyj;tmzj-dp=pzj;tmwj-dp=Wj;Nurbs2ControlPoint(mu,U,tmx,tmw,tmpxi);Nurbs2ControlPoint(mu,U,tmy,tmw,tmpyi);Nurbs2ControlPoint(mu,U,tmz,tmw,tmpzi);B2SplineControlPoint(mu,U,tmw,。

    16、tmpwi);for(i=0;i2*mu-7;i+)for(j=0;jmv-2;j+)tmxj=tmpxji;tmyj=tmpyji;tmzj=tmpzji;tmwj=tmpwji;Nurbs2ControlPoint(mv,V,tmx,tmw,uvxi);Nurbs2ControlPoint(mv,V,tmy,tmw,uvyi);Nurbs2ControlPoint(mv,V,tmz,tmw,uvzi);B2SplineControlPoint(mv,V,tmw,uvwi);for(k=0;k2*mv-7;k+)ptik0=uvxik;ptik1=uvyik;ptik2=uvzik;ptik。

    17、3=uvwik;/-/计算双三次(3x3次)或双二次(2x2次)Nurbs样条曲面上所有的点并保存在bs中/nu,mv分别为节点矢量U,V的最大下标/uk,vk分别为B样条曲面(u,v)方向上的网格数/p为曲面的次数void NurbsFace(int p,int nu,float U,int uk,int mv,float V,int vk,float px,float py,float pz,float w,float bs1611613)int udk20,vdk20,i,j,k,l,hu,sv,du,dv;float tp1001004,td1611613;float tmx44,tm。

    18、y44,tmz44,tmw44;du=nu-2*p;dv=mv-2*p;SetGridCount(du,uk,udk);SetGridCount(dv,vk,vdk);if(p=3)Nurbs3FControlPoint(nu,U,mv,V,px,py,pz,w,tp);if(p=2)Nurbs2FControlPoint(nu,U,mv,V,px,py,pz,w,tp);for(i=0;idv;i+)for(k=0;kdu;k+)for(j=i*p;jp+1+i*p;j+)for(l=k*p;lp+1+k*p;l+)tmxj-i*pl-k*p=tplj0;tmyj-i*pl-k*p=tplj1;tmzj-i*pl-k*p=tplj2。

    展开全文
  • 半结构化B样条曲线,用于混合两个B样条曲线曲面
  • B样条曲线曲面 Mfc

    热门讨论 2012-02-26 11:08:27
    本程序利用MFC实现了B样条曲线曲面的绘制:均匀B样条曲线 准均匀B样条曲线 分段Bezier曲线 非均匀B样条曲线 曲面
  • B样条曲线曲面降阶综述
  • 论文构造了一类带多个形状参数的指数均匀B样条曲线曲面,它保持了指数均匀B样条曲线曲面的主要性质(如连续性、凸包性等)。此类曲线在不改变控制顶点的情况下,通过改变其形状参数的取值,可以生成多条逼近于控制多边形...
  • B样条曲线曲面,Coons曲面,有理样条曲线曲面
  • 类二次均匀B样条曲线曲面,姚兴,杭后俊,在工程应用中,由于形状参数的直观和灵活,已成为调节曲线曲面形状的实用方法。本文主要讨论二次均匀B样条曲线曲面的扩展,首先��
  • 关于Bezier曲线曲面和B样条曲线曲面的介绍,以及它们在绘图工具中的使用情况。小论文的形式。
  • 基于OpenGL的B样条曲线曲面的绘制

    热门讨论 2009-02-12 11:05:04
    基于OpenGL的B样条曲线曲面的绘制算法,包含了均匀、准均匀、Bezier、各种非均匀B样条曲线曲面的绘制,阶次的升降,以及曲面的光照和纹理映射算法。
  • B样条曲线曲面的节点消去算法研究 ,对于研究B样条曲线曲面的人又帮助!
  • 文章给出了一种新的8样条曲线曲面光顺算法,该算法以型值点的变动量为未知量,以型值点变动量的变动范围为约束条件,给出能量函数;...最后给出实例,表明该B样条曲线曲面光顺算法是一种有效的光顺算法。
  • B样条曲线曲面密集控制点是造成CAD模型数据量庞大的因素之一,对其进行压缩编码,能有效减少CAD模型数据量。提出一种局部坐标系下二阶预测编码算法,对B样条控制网格构造局部坐标系,在局部坐标系下对控制点进行一阶...
  • 应用基于展开的增量法生成非均匀B样条曲线曲面以及NURBS曲线,给出一个较简单高效的算法。此算法仅在初始化时进行乘除运算而后均为加法迭代,相较于deBoor算法效率更高。
  • TC-B样条保留了B样条的优点,克服了...文章给出了n次均匀TC-B样条基函数的递推表达式,讨论三次TC-B样条曲线段之间及其与二次TC-B样条曲线段的Gl和G2拼接,并给出了均匀剖分上的双二次TC-B样条曲面片的G1和G2连续条件。
  • B样条(B-Spline)曲线及曲面在计算机辅助设计应用上较Bezier及Cubic曲线广泛,因B样条曲线是包含Bezier曲线的通用数学表示法。与Bezier曲线相比,B样条曲线可以将曲线的阶数由控制点个数决定的情况下独立出来,即由...

    B样条

    B样条(B-Spline)曲线及曲面在计算机辅助设计应用上较Bezier及Cubic曲线广泛,因B样条曲线是包含Bezier曲线的通用数学表示法。与Bezier曲线相比,B样条曲线可以将曲线的阶数由控制点个数决定的情况下独立出来,即由四个控制点定义的Bezier曲线只能建立三次曲线,而B样条曲线可以建立一次至三次不同的曲线。

    B样条曲线具有这些特性的原因在于其选择的基底函数(Basis function)与Bezier曲线不同。

    B样条数学模型

    B样条曲线

    1. 定义
    P1,P1,P2,...,Pn+1为给定空间的n+1个点,则下列参数曲线

    P(u)=i=1n+1BiNi,k(u)
    uminuumax,
    2kn+1

    k阶(次数degree k1次)的B样条曲线,折线P1P1P2...Pn+1P(t)的控制多边形,点集{Pi}P(u)的控制顶点,Ni,k(u)为正规化的B样条基底函数(Normalized B-Spline basis function)。

    阶数为k时,第i个基底函数BiNi,k(u)由Cox-deBoor递推关系可定义为,

    Ni,1(u)={1,if uiuui+10,otherwise
    Ni,k(u)=(uui)Ni,k1(u)ui+k1ui+(ui+kt)Ni+1,k1(u)ui+kui+1

    ui为节点向量U(Knot vector)中的第i个元素,且uiui+1

    B样条曲面

    1. 定义
    B样条曲面与B样条曲线性质相同,在曲面u方向的正规化基底函数Ni,k(u)及节点向量U外,再加上v方向的正规化基底函数Ni,k(v)及节点向量V。曲面控制顶点分布由一维(n+1)变为二维的(n+1)×(m+1),且二维的控制点分布必须满足拓扑上的矩形分布。B样条曲面表示如下:

    S(u,v)=i=1n+1j=1m+1Bi,jNi,k(u)Nj,q(v)

    基底函数的表示与B样条曲线中的表示形式相同。

    B样条模型特性

    节点向量

    节点向量是决定B样条基底函数的重要参数。若有相同控制点,而节点向量不同,曲线形状也将不同。B样条可用的参数区间范围为k1in+1
    通常要求节点向量中元素单调递增,节点向量有三种形式:

    • 均匀分布(Uniform):
      均匀分布节点向量内的节点值以等差级数方式排列,且一般第一个元素值为0。均匀分布节点向量,会使B样条曲线全部的基底函数形状相同,除非重复首尾的控制点,否则B样条曲线的首尾两端不会落在首尾的控制点上
    • 开放均匀分布(Open uniform or Open):
      k阶的B样条曲线,其开放均匀节点向量的前面及倒数k个元素必须分别为最小和最大的k个重复值,从而可以充分用到每一个参数值。
    • 非均匀分布(Nonuniform):
      非均匀分布节点向量所形成的的基底函数的形状较不可预期,由于第k阶基底函数,非零值区间的边界皆落在节点向量的元素值上,因此非均匀节点向量常形成许多形状不同的基底函数曲线。

    节点向量中的元素值使参数空间被划分成几个子区间,一个基底函数具有非零值的区域,即落在该函数所属的参数子区间中,而各基底函数所属的子区间可以彼此重叠。故当B样条参数值由小增大时,控制点对曲线形状的影响会依序发生。

    展开全文
  • b样条曲线曲面显示

    2008-06-07 12:11:52
    一个介绍各种b样条 曲面曲线显示的程序,打开就能运行,用opengl编写的
  • B样条曲线曲面介绍

    2020-07-02 20:50:03
    B样条基函数 B样条基函数的定义 由de Boor和Cox分别导出B样条基函数的递推定义,B样条基函数可以表示为 Ni,0(u)={1,ui⩽u<ui+10,其他Ni,p(u)=u−uiui+p−uiNi,p−1(u)+ui+p+1−uui+p+1−ui+1Ni+1,p−1(u),p>0 ...

    B样条基函数

    B样条基函数的定义

    由de Boor和Cox分别导出B样条基函数的递推定义,B样条基函数可以表示为
    Ni,0(u)={1,uiu<ui+10,Ni,p(u)=uuiui+puiNi,p1(u)+ui+p+1uui+p+1ui+1Ni+1,p1(u),p>0 \begin{aligned} N_{i,0}(u) &= \begin{cases} 1 ,\quad u_i \leqslant u < u_{i+1} \\ 0 ,\quad 其他 \end{cases} \\ N_{i,p}(u) &= \dfrac{u-u_i}{u_{i+p}-u_i}N_{i,p-1}(u)+\dfrac{u_{i+p+1}-u}{u_{i+p+1}-u_{i+1}}N_{i+1,p-1}(u) ,\quad p > 0 \end{aligned}
    并约定0/0=00/0=0。式中pp表示B样条的幂次,uu为节点,下标ii为B样条的序号。

    上式表明,任意pp次B样条基函数可由两个相邻的p1p-1次B样条基函数的线性组合构成。

    B样条基函数的性质

    • 如果u[ui,ui+p+1)u\notin\left[u_i,u_{i+p+1}\right),则Ni,p(u)=0N_{i,p}(u)=0
    • u[ui,ui+1)u\in\left[u_i,u_{i+1}\right)时,j=ipiNj,p(u)=1\sum\limits_{j=i-p}^{i}N_{j,p}(u)=1

    B样条基函数的导数

    B样条基函数的求导公式为
    Ni,p(u)=pui+puiNi,p1(u)pui+p+1ui+1Ni+1,p1(u). N^{'}_{i,p}(u)=\dfrac{p}{u_{i+p}-u_i}N_{i,p-1}(u)-\dfrac{p}{u_{i+p+1}-u_{i+1}}N_{i+1,p-1}(u).
    下面通过对pp利用数学归纳法来证明求导公式。当p=1p=1时,Ni,p1(u)N_{i,p-1}(u)Ni+1,p1(u)N_{i+1,p-1}(u) 在每个节点区间内或者为00,或者为11,因此Ni,p(u)N^{'}_{i,p}(u) 等于1ui+1ui\dfrac{1}{u_{i+1}-u_i}或者1ui+2ui+1-\dfrac{1}{u_{i+2}-u_{i+1}}。我们假设当p1(p>1)p-1(p>1)时求导公式成立。根据求导法则(fg)=fg+fg(fg)^{'}=f^{'}g+fg^{'},对基函数
    Ni,p(u)=uuiui+puiNi,p1(u)+ui+p+1uui+p+1ui+1Ni+1,p1(u) N_{i,p}(u)=\dfrac{u-u_i}{u_{i+p}-u_i}N_{i,p-1}(u)+\dfrac{u_{i+p+1}-u}{u_{i+p+1}-u_{i+1}}N_{i+1,p-1}(u)
    求导,得到
    Ni,p(u)=1ui+puiNi,p1(u)+uuiui+puiNi,p1(u)1ui+p+1ui+1Ni+1,p1(u)+ui+p+1uui+p+1ui+1Ni+1,p1(u)=1ui+puiNi,p1(u)1ui+p+1ui+1Ni+1,p1(u)+uuiui+pui(p1ui+p1uiNi,p2(u)p1ui+pui+1Ni+1,p2(u))+ui+p+1uui+p+1ui+1(p1ui+pui+1Ni+1,p2(u)p1ui+p+1ui+2Ni+2,p2(u))=1ui+puiNi,p1(u)1ui+p+1ui+1Ni+1,p1(u)+p1ui+puiuuiui+p1uiNi,p2(u)+p1ui+pui+1(ui+p+1uui+p+1ui+1uuiui+pui)Ni+1,p2(u)p1ui+p+1ui+1ui+p+1uui+p+1ui+2Ni+2,p2(u). \begin{aligned} N^{'}_{i,p}(u)=& \dfrac{1}{u_{i+p}-u_i}N_{i,p-1}(u)+\dfrac{u-u_i}{u_{i+p}-u_i}N^{'}_{i,p-1}(u) \\ &-\dfrac{1}{u_{i+p+1}-u_{i+1}}N_{i+1,p-1}(u)+\dfrac{u_{i+p+1}-u}{u_{i+p+1}-u_{i+1}}N^{'}_{i+1,p-1}(u) \\ =& \dfrac{1}{u_{i+p}-u_i}N_{i,p-1}(u)-\dfrac{1}{u_{i+p+1}-u_{i+1}}N_{i+1,p-1}(u) \\ &+\dfrac{u-u_i}{u_{i+p}-u_i}\left(\dfrac{p-1}{u_{i+p-1}-u_i}N_{i,p-2}(u)-\dfrac{p-1}{u_{i+p}-u_{i+1}}N_{i+1,p-2}(u)\right) \\ &+\dfrac{u_{i+p+1}-u}{u_{i+p+1}-u_{i+1}}\left(\dfrac{p-1}{u_{i+p}-u_{i+1}}N_{i+1,p-2}(u)-\dfrac{p-1}{u_{i+p+1}-u_{i+2}}N_{i+2,p-2}(u)\right) \\ =& \dfrac{1}{u_{i+p}-u_i}N_{i,p-1}(u)-\dfrac{1}{u_{i+p+1}-u_{i+1}}N_{i+1,p-1}(u) \\ &+\dfrac{p-1}{u_{i+p}-u_i}\dfrac{u-u_i}{u_{i+p-1}-u_i}N_{i,p-2}(u) \\ &+\dfrac{p-1}{u_{i+p}-u_{i+1}}\left(\dfrac{u_{i+p+1}-u}{u_{i+p+1}-u_{i+1}}-\dfrac{u-u_i}{u_{i+p}-u_i}\right)N_{i+1,p-2}(u) \\ &-\dfrac{p-1}{u_{i+p+1}-u_{i+1}}\dfrac{u_{i+p+1}-u}{u_{i+p+1}-u_{i+2}}N_{i+2,p-2}(u). \end{aligned}
    由于
    ui+p+1uui+p+1ui+1uuiui+pui=1+ui+p+1uui+p+1ui+1+1uuiui+pui=ui+p+1ui+1ui+p+1ui+1+ui+p+1uui+p+1ui+1+ui+puiui+puiuuiui+pui=ui+puui+puiuui+1ui+p+1ui+1. \begin{aligned} \dfrac{u_{i+p+1}-u}{u_{i+p+1}-u_{i+1}}-\dfrac{u-u_i}{u_{i+p}-u_i}=& -1+\dfrac{u_{i+p+1}-u}{u_{i+p+1}-u_{i+1}}+1-\dfrac{u-u_i}{u_{i+p}-u_i} \\ =& -\dfrac{u_{i+p+1}-u_{i+1}}{u_{i+p+1}-u_{i+1}}+\dfrac{u_{i+p+1}-u}{u_{i+p+1}-u_{i+1}} \\ & +\dfrac{u_{i+p}-u_i}{u_{i+p}-u_i}-\dfrac{u-u_i}{u_{i+p}-u_i} \\ =&\dfrac{u_{i+p}-u}{u_{i+p}-u_i}-\dfrac{u-u_{i+1}}{u_{i+p+1}-u_{i+1}}. \end{aligned}
    于是得到
    Ni,p(u)=1ui+puiNi,p1(u)1ui+p+1ui+1Ni+1,p1(u)+p1ui+pui(uuiui+p1uiNi,p2(u)+ui+puui+pui+1Ni+1,p2(u))p1ui+p+1ui+1(uui+1ui+pui+1Ni+1,p2(u)+ui+p+1uui+p+1ui+2Ni+2,p2(u))=1ui+puiNi,p1(u)1ui+p+1ui+1Ni+1,p1(u)+p1ui+puiNi,p1(u)p1ui+p+1ui+1Ni+1,p1(u)=pui+puiNi,p1(u)pui+p+1ui+1Ni+1,p1(u). \begin{aligned} N^{'}_{i,p}(u)=& \dfrac{1}{u_{i+p}-u_i}N_{i,p-1}(u)-\dfrac{1}{u_{i+p+1}-u_{i+1}}N_{i+1,p-1}(u) \\ &+\dfrac{p-1}{u_{i+p}-u_i}\left(\dfrac{u-u_i}{u_{i+p-1}-u_i}N_{i,p-2}(u)+\dfrac{u_{i+p}-u}{u_{i+p}-u_{i+1}}N_{i+1,p-2}(u)\right) \\ &-\dfrac{p-1}{u_{i+p+1}-u_{i+1}}\left(\dfrac{u-u_{i+1}}{u_{i+p}-u_{i+1}}N_{i+1,p-2}(u)+\dfrac{u_{i+p+1}-u}{u_{i+p+1}-u_{i+2}}N_{i+2,p-2}(u)\right) \\ =& \dfrac{1}{u_{i+p}-u_i}N_{i,p-1}(u)-\dfrac{1}{u_{i+p+1}-u_{i+1}}N_{i+1,p-1}(u) \\ &+\dfrac{p-1}{u_{i+p}-u_i}N_{i,p-1}(u)-\dfrac{p-1}{u_{i+p+1}-u_{i+1}}N_{i+1,p-1}(u) \\ =& \dfrac{p}{u_{i+p}-u_i}N_{i,p-1}(u)-\dfrac{p}{u_{i+p+1}-u_{i+1}}N_{i+1,p-1}(u). \end{aligned}
    证毕。

    B样条曲线曲面

    B样条曲线的定义

    pp次B样条曲线的定义为
    P(u)=i=0nNi,p(u)Vi,aub P\left(u\right)=\sum\limits_{i=0}^{n}N_{i,p}(u)V_i,\quad a\leqslant u\leqslant b
    这里{Vi}\left\{V_i\right\}是控制点,{Ni,p(u)}\left\{N_{i,p}(u)\right\}是定义在非周期(并且非均匀)节点矢量
    U={a,,ap+1,up+1,,ump1,b,,bp+1} U = \left\{ \underbrace{a,\cdots,a}_{p+1}, u_{p+1},\cdots,u_{m-p-1}, \underbrace{b,\cdots,b}_{p+1} \right\}
    (包含m+1m+1个节点)上的pp次B样条基函数。由{Vi}\left\{V_i\right\}构成的多边形称为控制多边形。

    有理B样条曲线曲面

    NURBS曲线的定义

    一条pp次NURBS曲线的定义为
    P(u)=i=0nNi,p(u)ωiVii=0nNi,p(u)ωi,aub P\left(u\right)=\dfrac{\sum\limits_{i=0}^{n}N_{i,p}(u)\omega_iV_i}{\sum\limits_{i=0}^{n}N_{i,p}(u)\omega_i},\quad a\leqslant u\leqslant b
    这里{Vi}\left\{V_i\right\}是控制点(它们形成控制多边形),{ωi}\left\{\omega_i\right\}是权因子,{Ni,p(u)}\left\{N_{i,p}(u)\right\}是定义在非周期(并且非均匀)节点矢量UU上的pp次B样条基函数。其中
    U={a,,ap+1,up+1,,ump1,b,,bp+1} U = \left\{ \underbrace{a,\cdots,a}_{p+1}, u_{p+1},\cdots,u_{m-p-1}, \underbrace{b,\cdots,b}_{p+1} \right\}

    展开全文
  • PCL——B样条曲线曲面拟合

    千次阅读 2020-08-06 21:35:19
    B样条曲线 样条曲线,是B-样条基函数的线性组合,是贝塞尔曲线的一般化。 给定n+1个控制点,P0,P1, …, Pn以及一个节点向量U = { u0,u1, …, um }, p 次B-样条曲线由这些控制点和节点向量U 定义,设Ni,p(u)是第i个 p...

    B样条曲线
    样条曲线,是B-样条基函数的线性组合,是贝塞尔曲线的一般化。
    给定n+1个控制点,P0,P1, …, Pn以及一个节点向量U = { u0,u1, …, um }, p 次B-样条曲线由这些控制点和节点向量U 定义,设Ni,p(u)是第i个 p次B-样条基函数,则p 次B-样条曲线的公式为
    在这里插入图片描述
    设P0、P02、P2是一条抛物线上顺序三个不同的点。过P0和P2点的两切线交于P1点,在P02点的切线交P0P1和P2P1于P01和P11
    在这里插入图片描述
    在这里插入图片描述
    引入比值为参数t则
    在这里插入图片描述
    将前两个式子代入到第三个式子得到:
    在这里插入图片描述
    二次Bezier曲线P02可以定义为分别由前两个顶点(P0,P1)和后两个顶点(P1,P2)决定的一次Bezier曲线的线性组合
    由此递推到n次Bezier曲线,可得到递推式:

    在这里插入图片描述
    什么是节点向量?
    设U 是m + 1个非递减数的集合,u0 <=u1 <= u2 <= … <= um。ui称为节点(knots), 集合U 称为节点向量(knot vector)
    因为可能存在一个节点出现多次,也叫多重节点。所以节点向量的维度不等于控制点的个数。

    B-样条基函数
    基函数的次数p,第i个p次B-样条基函数,写为Ni,p(u),递归定义如下:
    在这里插入图片描述
    此处规定了0/0=0。 式中p表示样条的幂次,下标i表示B样条的序号。该递推公式表明,任意p次样条可由两个相邻的p-1次样条的线性组合构成。计算Ni,p(u),可以依据三角计算格式
    在这里插入图片描述
    B样条曲线曲面重建的原理
    基于B样条曲线的曲面重建实质上就是根据控制点进行B样条曲面拟合。B 样条曲面是由多条 B 样条曲线在 u、v 两个方向上多次构建形成的,由(m+1)×(n+1)个控制点构成一张控制网格,两个方向的参数节点矢量分别为U=[u0,u1…um+k+1]和V=[v0,v1…vm+l+1]。B样条曲面的方程的定义如下
    在这里插入图片描述
    Pi,j是控制点集Pi,j(i=0,1…m;j=0,1…n),也就是三维点云中的点集(局部)。Ni,k(u)和Nj,l(v)是B样条曲面基函数。
    在这里插入图片描述
    拟合的过程很简单,拟合后求曲面方程系数的步骤:
    1)固定 j,对于Pi,j(i=0,1…m;j=0,1…n)沿u 方向分别求出 n+1条参数曲线的控制顶点。
    2)固定 i,对于Pi,j(i=0,1…m;j=0,1…n)沿v 方向分别求出 m+1条参数曲线的控制顶点。
    PCL中基于B样条曲线的曲面重建
    算法流程
    1,使用主成分分析(PCA)初始化B样条曲面。这假设点云有两个主要的方向,即它大致是平面的。
    2,对初始化后的B样条曲面进行拟合和迭代优化。
    3,用圆来对B样条曲线初始化。这里我们假设点云是紧凑的,即没有分离的聚类。
    4,对初始化后的B样条曲线进行拟合。
    5,对拟合得到的B样条曲面进行三角化,得到最终的曲面模型。
    PCL实现
    // parameters
    unsigned order (3);
    unsigned refinement (5);
    unsigned iterations (10);
    unsigned mesh_resolution (256);

    pcl::on_nurbs::FittingSurface::Parameter params;
    params.interior_smoothness = 0.2;
    params.interior_weight = 1.0;
    params.boundary_smoothness = 0.2;
    params.boundary_weight = 0.0;
    Order ——B样条曲面的多项式阶
    Refinemen——是求精迭代的次数,其中每插入一个迭代控制点,b样条曲面的每个参数方向上的控制点大约翻倍。
    Iterations——是优化完成后执行的迭代数量。
    mesh_resolutio——每个参数方向上的顶点数,用于b样条曲面的三角剖分。
    interior_smoothness——内部表面的光滑度
    interior_weight——用于表面内部优化的权重。
    boundary_smoothness——表面边界的平滑度
    boundary_weight——表面边界优化的权重
    B样条拟合曲面的相关参数解读:
    pcl::on_nurbs::FittingCurve2dAPDM::FitParameter curve_params;
    curve_params.addCPsAccuracy = 5e-2;//曲线的支持区域到最近数据点的距离必须低于该值,否则将插入控制点。
    curve_params.addCPsIteration = 3;//内部迭代没有插入控制点。
    curve_params.maxCPs = 200;//控制点的最大总数
    curve_params.accuracy = 1e-3;//曲线的拟合精度
    curve_params.iterations = 100;//迭代次数

    curve_params.param.closest_point_resolution = 0;//每个支持区域内的控制点数量
    curve_params.param.closest_point_weight = 1.0;//曲线拟合到最近点的权值
    curve_params.param.closest_point_sigma2 = 0.1;//最近点的阈值
    curve_params.param.interior_sigma2 = 0.00001;//内点的阈值
    curve_params.param.smooth_concavity = 1.0;//导致曲线向内弯曲的值(0 =不弯曲;< 0向内弯曲;> 0向外弯曲)
    curve_params.param.smoothness = 1.0;//平滑项的权值
    拟合B样条曲面结果:
    在这里插入图片描述
    在这里插入图片描述
    附上代码:

    #include <pcl/point_cloud.h>
    #include <pcl/point_types.h>
    #include <pcl/io/pcd_io.h>
    
    #include <pcl/visualization/pcl_visualizer.h>
    #include <pcl/surface/on_nurbs/fitting_surface_tdm.h>
    #include <pcl/surface/on_nurbs/fitting_curve_2d_asdm.h>
    #include <pcl/surface/on_nurbs/triangulation.h>
    #include <pcl/console/parse.h>
    using namespace pcl::console;
    typedef pcl::PointXYZ Point;
    
    void
    PointCloud2Vector3d(pcl::PointCloud<Point>::Ptr cloud, pcl::on_nurbs::vector_vec3d &data);
    
    void
    visualizeCurve(ON_NurbsCurve &curve,
    	ON_NurbsSurface &surface,
    	pcl::visualization::PCLVisualizer &viewer);
    
    int
    main(int argc, char *argv[])
    {
    	std::string pcd_file, file_3dm;
    
    	if (argc < 2)
    	{
    		printf("\nUsage: pcl_example_nurbs_fitting_surface pcd<PointXYZ>-in-file -o 3 -rn 4 -in 10 -mr 128 -td 1\n\n");
    		exit(0);
    	}
    	pcd_file = argv[1];
    	//file_3dm = argv[2];
    
    	pcl::visualization::PCLVisualizer viewer("点云库PCL学习教程第二版-B样条曲面拟合点云数据");
    	viewer.setBackgroundColor(255, 255, 255);
    	viewer.setSize(800, 600);
    
    	// ############################################################################
    	// load point cloud
    
    	printf("  loading %s\n", pcd_file.c_str());
    	pcl::PointCloud<Point>::Ptr cloud(new pcl::PointCloud<Point>);
    	pcl::PCLPointCloud2 cloud2;
    	pcl::on_nurbs::NurbsDataSurface data;
    
    	if (pcl::io::loadPCDFile(pcd_file, cloud2) == -1)
    		throw std::runtime_error("  PCD file not found.");
    
    	fromPCLPointCloud2(cloud2, *cloud);
    	PointCloud2Vector3d(cloud, data.interior);
    	pcl::visualization::PointCloudColorHandlerCustom<Point> handler(cloud, 0, 255, 0);
    	viewer.addPointCloud<Point>(cloud, handler, "cloud_cylinder");
    	printf("  %lu points in data set\n", cloud->size());
    
    	// ############################################################################
    	// fit B-spline surface
    
    	// parameters
    	unsigned order(3);
    	unsigned refinement(4);
    	unsigned iterations(10);
    	unsigned mesh_resolution(128);
    	bool two_dim = true;
    	parse_argument(argc, argv, "-o", order);
    	parse_argument(argc, argv, "-rn", refinement);
    	parse_argument(argc, argv, "-in", iterations);
    	parse_argument(argc, argv, "-mr", mesh_resolution);
    	parse_argument(argc, argv, "-td", two_dim);
    	pcl::on_nurbs::FittingSurface::Parameter params;
    	params.interior_smoothness = 0.2;
    	params.interior_weight = 1.0;
    	params.boundary_smoothness = 0.2;
    	params.boundary_weight = 0.0;
    
    	// initialize
    	printf("  surface fitting ...\n");
    	ON_NurbsSurface nurbs = pcl::on_nurbs::FittingSurface::initNurbsPCABoundingBox(order, &data);
    	pcl::on_nurbs::FittingSurface fit(&data, nurbs);
    	//  fit.setQuiet (false); // enable/disable debug output
    
    	// mesh for visualization
    	pcl::PolygonMesh mesh;
    	pcl::PointCloud<pcl::PointXYZ>::Ptr mesh_cloud(new pcl::PointCloud<pcl::PointXYZ>);
    	std::vector<pcl::Vertices> mesh_vertices;
    	std::string mesh_id = "mesh_nurbs";
    	pcl::on_nurbs::Triangulation::convertSurface2PolygonMesh(fit.m_nurbs, mesh, mesh_resolution);
    	viewer.addPolygonMesh(mesh, mesh_id);
    	std::cout << "Before refine" << endl;
    	viewer.spinOnce(3000);
    	// surface refinement
    	for (unsigned i = 0; i < refinement; i++)
    	{
    		fit.refine(0);
    		if (two_dim)fit.refine(1);
    		fit.assemble(params);
    		fit.solve();
    		pcl::on_nurbs::Triangulation::convertSurface2Vertices(fit.m_nurbs, mesh_cloud, mesh_vertices, mesh_resolution);
    		viewer.updatePolygonMesh<pcl::PointXYZ>(mesh_cloud, mesh_vertices, mesh_id);
    		viewer.spinOnce(3000);
    		std::cout << "refine: " << i << endl;
    	}
    	// surface fitting with final refinement level
    	for (unsigned i = 0; i < iterations; i++)
    	{
    		fit.assemble(params);
    		fit.solve();
    		pcl::on_nurbs::Triangulation::convertSurface2Vertices(fit.m_nurbs, mesh_cloud, mesh_vertices, mesh_resolution);
    		viewer.updatePolygonMesh<pcl::PointXYZ>(mesh_cloud, mesh_vertices, mesh_id);
    		viewer.spinOnce(3000);
    		std::cout << "iterations: " << i << endl;
    	}
    	// ############################################################################
    	// fit B-spline curve
    
    	// parameters
    	pcl::on_nurbs::FittingCurve2dAPDM::FitParameter curve_params;
    	curve_params.addCPsAccuracy = 5e-2;
    	curve_params.addCPsIteration = 3;
    	curve_params.maxCPs = 200;
    	curve_params.accuracy = 1;
    	curve_params.iterations = 100;
    
    	curve_params.param.closest_point_resolution = 0;
    	curve_params.param.closest_point_weight = 1.0;
    	curve_params.param.closest_point_sigma2 = 0.1;
    	curve_params.param.interior_sigma2 = 0.00001;
    	curve_params.param.smooth_concavity = 1.0;
    	curve_params.param.smoothness = 1.0;
    
    	// initialisation (circular)
    	printf("  curve fitting ...\n");
    	pcl::on_nurbs::NurbsDataCurve2d curve_data;
    	curve_data.interior = data.interior_param;
    	curve_data.interior_weight_function.push_back(true);
    	ON_NurbsCurve curve_nurbs = pcl::on_nurbs::FittingCurve2dAPDM::initNurbsCurve2D(order, curve_data.interior);
    	// curve fitting
    	pcl::on_nurbs::FittingCurve2dASDM curve_fit(&curve_data, curve_nurbs);
    	// curve_fit.setQuiet (false); // enable/disable debug output
    	curve_fit.fitting(curve_params);
    	visualizeCurve(curve_fit.m_nurbs, fit.m_nurbs, viewer);
    
    	// ############################################################################
    	// triangulation of trimmed surface
    
    	printf("  triangulate trimmed surface ...\n");
    	viewer.removePolygonMesh(mesh_id);
    	pcl::on_nurbs::Triangulation::convertTrimmedSurface2PolygonMesh(fit.m_nurbs, curve_fit.m_nurbs, mesh,
    		mesh_resolution);
    	viewer.addPolygonMesh(mesh, mesh_id);
    
    
    	// save trimmed B-spline surface
    	/*if ( fit.m_nurbs.IsValid() )
    	{
    	  ONX_Model model;
    	  ONX_Model_Object& surf = model.m_object_table.AppendNew();
    	  surf.m_object = new ON_NurbsSurface(fit.m_nurbs);
    	  surf.m_bDeleteObject = true;
    	  surf.m_attributes.m_layer_index = 1;
    	  surf.m_attributes.m_name = "surface";
    	  ONX_Model_Object& curv = model.m_object_table.AppendNew();
    	  curv.m_object = new ON_NurbsCurve(curve_fit.m_nurbs);
    	  curv.m_bDeleteObject = true;
    	  curv.m_attributes.m_layer_index = 2;
    	  curv.m_attributes.m_name = "trimming curve";
    	  model.Write(file_3dm.c_str());
    	  printf("  model saved: %s\n", file_3dm.c_str());
    	}*/
    
    	printf("  ... done.\n");
    
    	viewer.spin();
    	return 0;
    }
    
    void
    PointCloud2Vector3d(pcl::PointCloud<Point>::Ptr cloud, pcl::on_nurbs::vector_vec3d &data)
    {
    	for (unsigned i = 0; i < cloud->size(); i++)
    	{
    		Point &p = cloud->at(i);
    		if (!pcl_isnan(p.x) && !pcl_isnan(p.y) && !pcl_isnan(p.z))
    			data.push_back(Eigen::Vector3d(p.x, p.y, p.z));
    	}
    }
    
    void
    visualizeCurve(ON_NurbsCurve &curve, ON_NurbsSurface &surface, pcl::visualization::PCLVisualizer &viewer)
    {
    	pcl::PointCloud<pcl::PointXYZRGB>::Ptr curve_cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
    
    	pcl::on_nurbs::Triangulation::convertCurve2PointCloud(curve, surface, curve_cloud, 4);
    	for (std::size_t i = 0; i < curve_cloud->size() - 1; i++)
    	{
    		pcl::PointXYZRGB &p1 = curve_cloud->at(i);
    		pcl::PointXYZRGB &p2 = curve_cloud->at(i + 1);
    		std::ostringstream os;
    		os << "line" << i;
    		viewer.removeShape(os.str());
    		viewer.addLine<pcl::PointXYZRGB>(p1, p2, 1.0, 0.0, 0.0, os.str());
    	}
    
    	pcl::PointCloud<pcl::PointXYZRGB>::Ptr curve_cps(new pcl::PointCloud<pcl::PointXYZRGB>);
    	for (int i = 0; i < curve.CVCount(); i++)
    	{
    		ON_3dPoint p1;
    		curve.GetCV(i, p1);
    
    		double pnt[3];
    		surface.Evaluate(p1.x, p1.y, 0, 3, pnt);
    		pcl::PointXYZRGB p2;
    		p2.x = float(pnt[0]);
    		p2.y = float(pnt[1]);
    		p2.z = float(pnt[2]);
    
    		p2.r = 255;
    		p2.g = 0;
    		p2.b = 0;
    
    		curve_cps->push_back(p2);
    	}
    	viewer.removePointCloud("cloud_cps");
    	viewer.addPointCloud(curve_cps, "cloud_cps");
    }
    

    命令参数:C:\\Users\\Administrator\\Desktop\\ConsoleApplication1\\13.pcd -rn 4 -in 10

    展开全文
  • B样条曲线曲面(附代码)

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

    万次阅读 多人点赞 2017-01-19 22:09:43
    两端点的切矢方向与控制多边形(特征多边形)的第一和最后一边一致: Bezier曲线的递推性—de Casteljau算法 de Casteljau算法绘制Bezier曲线:#define nctlPoints 5 //控制点数 #d
  • 文件名称: nurbs_toolbox下载 收藏√ [5 4 3 2 1]开发工具: matlab文件大小: 45 KB上传时间: 2016-02-14下载次数: 0提 供 者: WCJ详细说明:非均匀有理B样条曲线曲面工具箱,用于MATLAB-NURBS toolbox in MATLAB文件...
  • #include <iostream>
  • B样条曲线曲面

    2012-10-14 12:17:23
    讲述B样条曲线曲面的发展历史,经典算法和未来的发展方向!
  • 阐述CAD系统曲线曲面的造型方法,主要介绍bezier曲线和B样条曲线的生成算法。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,288
精华内容 915
关键字:

b样条曲线曲面