B样条曲线曲面(附代码)

摘要:
不同类型的B样条曲线区别主要在于节点矢量,对于具有n+1个控制顶点的k次B样条曲线,无论是哪种类型都具有n+k+2个节点。均匀B样条曲线节点矢量中节点为沿参数轴均匀或等距分布。这里给出准均匀B样条和分段Bezier曲线的生成节点矢量的代码,均匀B样条的很简单就不列出了。关于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样条曲线的定义的核心,该公式在程序中的实现可采用递归的方式:

B样条曲线曲面(附代码)第3张B样条曲线曲面(附代码)第4张
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]

B样条曲线曲面(附代码)第9张clip_image016[4]

准均匀B样条曲线

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

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

B样条曲线曲面(附代码)第12张clip_image022[4]

分段Bezier曲线

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

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

B样条曲线曲面(附代码)第16张clip_image030[4]

一般非均匀B样条曲线

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

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

B样条曲线曲面(附代码)第19张B样条曲线曲面(附代码)第20张
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样条节点向量
B样条曲线曲面(附代码)第21张B样条曲线曲面(附代码)第22张
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.

免责声明:文章转载自《B样条曲线曲面(附代码)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇[Tomcat/Java EE/Linux]Tomcat启动异常:StandardServer.await: create[localhost:8005]: java.net.BindException: 无法指定被请求的地址Opencv之斑点(Blob)检测SimpleBlobDetector_create下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Unity3D之Mesh(一)绘制三角形

前言: Unity自带几种简单的模型,如cube等;一般情况下,其余模型有3D建模软件生成,以合适的文件格式导入unity中;而mesh(以我目前很粗浅的了解)的一般用途就是:对现有的模型进行变形,以达到各种奇幻酷炫的表现效果。 但是由于自己的项目需要,需要由数据(外部解释stl文件获得)按照特定情况以及要求实时地产生各种几何模型,故需要用Mesh进行建模...

OpenGL ES着色器语言----------------储存修饰符

一、存储修饰符 本地变量只能使用存储修饰符const。 函数参数只能用const。函数返回值类型和结构体字段不要使用const。 从一个运行时着色器到下一个运行时着色器之间进行数据类型通信是不存在的。这阻止了同一个着色器在多个顶点和片元之间同时执行。 没有存储修饰符或仅仅使用const修饰符的全局变量,可能在main()执行前进行初始化。Uniforms...

Geometry shader总结

什么是Geometry Shader GS存在于vertext shader和固定功能vertex post-processing stage之间,它是可选的不是必要的。GS的输入是单个primitive,输出可能是0个或多个primitive.  GS的作用 GS的主要作用就是从已有的primitive中生成新的primitive,它可以“无中生有”的...

OpenGL实现多层绘制(Layered Rendering) [转]

http://blog.csdn.net/u010462297/article/details/50589991 引言 在某些情况下会需要用到多层绘制。FBO下有多个颜色挂接点(Color Attachment),可以用不同的挂接点挂接不同的纹理对象,实现绘制多张纹理(MRT),这在之前的文章里已经有所描述。但是有时候这种方法是不够好用的: - 当纹理非...

win32下的OpenGL绘图环境框架

Win32下OpenGL入门 主要的步骤包括:添加opengl头文件,库文件,键盘鼠标响应,像素格式设置,opengl环境初始化,绘图变量设置,创建窗口,窗口大小改变时响应,绘制场景,源文件 1,新建一个win32项目(注意,不是console程序),在添加过程中,创建一个空的项目,然后,在解决方案资源管理器的源文件树目录下,添加一个cpp文件,文件可以命...

[原] OpenGL ES 学习笔记 (一)

1.OpenGL ES 的坐标系在屏幕上的分布 OpenGL ES 的坐标系{x, y, z} 通过图片的三维坐标系可以知道: - 它是一个三维坐标系 {x, y, z} - 三维坐标中心在正方体的几何中心 {0, 0, 0} - 整个坐标系是 [0, 1] 的点,也就是说 OpenGL 中只支持 0 ~ 1 的点 (这里所讲的 0 和 1 ,最好理...