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

其中,di(i=0,1...n)为控制顶点(坐标),Ni,k(i=0,1...n)为k次规范B样条基函数,最高次数是k。基函数是由一个称为节点矢量的非递减参数u的序列U:u0≤u1≤...≤un+k+1所决定的k次分段多项式。
B样条的基函数通常采用Cox-deBoor递推公式:
(2)
式中i为节点序号,k是基函数的次数,共有n+1个控制顶点。注意区分节点和控制顶点,节点是在节点矢量U中取得,控制顶点则是坐标点,决定B样条的控制多边形。Cox-deBoor递推公式是B样条曲线的定义的核心,该公式在程序中的实现可采用递归的方式:
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
Cox-deBoor递推公式
所给程序可用于计算基函数Ni,k(u)的值,程序中对不同类型的B样条曲线区别在于节点矢量 NodeVector 的取值不同。
1.2 B样条曲线的分类
根据节点矢量中节点的分布情况不同,可以划分4中类型的B样条曲线。不同类型的B样条曲线区别主要在于节点矢量,对于具有n+1个控制顶点
的 k 次B样条曲线,无论是哪种类型都具有n+k+2个节点
。

均匀B样条曲线
节点矢量中节点为沿参数轴均匀或等距分布。
对应的节点矢量:


准均匀B样条曲线
其节点矢量中两端节点具有重复度k+1,即u0=u1=...=uk,un+1=un+2=...=un+k+1,所有的内节点均匀分布,具有重复度1。
对应的节点矢量:


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


一般非均匀B样条曲线
对任意分布的节点矢量
,只要在数学上成立都可选取。
这里给出准均匀B样条和分段Bezier曲线的生成节点矢量的代码,均匀B样条的很简单就不列出了。假设共n+1个控制顶点,k次B样条,输入参数为 n, k ,输出节点矢量到NodeVector中。
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
准均匀B样条节点向量
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
分段Bezier曲线的节点向量
1.3 B样条曲线的计算
根据B样条曲线的定义公式(1),曲线上任一点坐标值是参数变量u的函数,用矩阵形式表示
(3)
可以看出只要已知控制顶点坐标
、曲线的次数
以及基函数
,就完全确定了B样条曲线,其中基函数
由Cox-deBoor 公式(2)递推计算。
2 B样条曲面
2.1 B样条曲面方程
确定一张
次张量积B样条曲面需要三个信息:
- 给定
个控制顶点
构成控制网格 - 给定参数
和
的次数
与
- u向和v向的节点矢量
,

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

,B样条基
与
分别由节点矢量
和
按Cox-deBoor递推公式(2)计算。
B样条曲面按照沿参数方向u, v所取的节点矢量不同,也可以划分成不同的类型:均匀、准均匀、分片Bezier和非均匀B样条曲面。
2.2 B样条曲面的计算
给定曲面的控制顶点并确定次数后,还需要根据不同类型的B样条曲面沿参数方向的节点矢量才能完全定义一张B样条曲面。要计算B样条曲面上的顶点坐标,首先沿一个参数方向如u向或v向,计算出该方向由控制顶点确定的B样条曲线,如下图中的红色曲线是沿u向生成的二次均匀B样条曲线,一共有四条。

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



参考文献:
[1] 施法中. 计算机辅助几何设计与非均匀有理B样条(修订版)[M]. 北京: 高等教育出版社, 2013.
B样条曲线曲面(附代码)的更多相关文章
- 分布式消息总线,基于.NET Socket Tcp的发布-订阅框架之离线支持,附代码下载
一.分布式消息总线以及基于Socket的实现 在前面的分享一个分布式消息总线,基于.NET Socket Tcp的发布-订阅框架,附代码下载一文之中给大家分享和介绍了一个极其简单也非常容易上的基于.N ...
- 分享5种风格的 jQuery 分页效果【附代码】
jPaginate 是一款非常精致的分页插件,提供了五种不同风格的分页效果,支持鼠标悬停翻页,快速分页功能.这款插件还提供了丰富的配置选项,你可以根据需要进行设置. 效果演示 源码下载 各个 ...
- Python进阶:函数式编程实例(附代码)
Python进阶:函数式编程实例(附代码) 上篇文章"几个小例子告诉你, 一行Python代码能干哪些事 -- 知乎专栏"中用到了一些列表解析.生成器.map.filter.lam ...
- c#万能视频播放器(附代码)
原文:c#万能视频播放器(附代码) c#万能视频播放器 本人之前很多的文章中均提到了使用libvlc为播放器内核制作的播放器,也许有些朋友对此感兴趣,于是我用c#写了一个调用libvlc api实现的 ...
- python德国信用评分卡建模(附代码AAA推荐)
欢迎关注博主主页,学习python视频资源,还有大量免费python经典文章 python信用评分卡建模视频系列教程(附代码) 博主录制 https://study.163.com/course/i ...
- 十图详解tensorflow数据读取机制(附代码)转知乎
十图详解tensorflow数据读取机制(附代码) - 何之源的文章 - 知乎 https://zhuanlan.zhihu.com/p/27238630
- 【转】- 从FM推演各深度CTR预估模型(附代码)
从FM推演各深度CTR预估模型(附代码) 2018年07月13日 15:04:34 阅读数:584 作者: 龙心尘 && 寒小阳 时间:2018年7月 出处: 龙心尘 寒小阳
- 数据挖掘领域十大经典算法之—C4.5算法(超详细附代码)
https://blog.csdn.net/fuqiuai/article/details/79456971 相关文章: 数据挖掘领域十大经典算法之—K-Means算法(超详细附代码) ...
- 【独家】阿里天池IJCAI17大赛第四名方案全解析(附代码)
[独家]阿里天池IJCAI17大赛第四名方案全解析(附代码) https://mp.weixin.qq.com/s?__biz=MzAxMzA2MDYxMw==&mid=2651560625& ...
- 球体的双目视觉定位(matlab,附代码)
球体的双目视觉定位(matlab,附代码) 标签(空格分隔): 机器视觉 引言 双目视觉定位是我们的一个课程设计,最近刚做完,拿出来与大家分享一下,实验的目的是在拍摄的照片中识别球体,并求出该球体到相 ...
随机推荐
- Java中的网络编程
Java中的网路编程主要是Java的Socket编程,属于JavaEE中的高级的部分,以下内容是对java网路编程的一个小结,代码都是经过编译调试的 C/S程序应用:客户/服务器模式,如QQ客户端 ...
- Android 数据库框架OrmLite的使用(一)
在这里记录下最基本的用法,官网上可了解相关的介绍. 1.下载OrmLite jar 在下载android的:ormlite-android-4.48.jar和ormlite-core-4.48.jar ...
- web前端学习随笔
为什么是随笔 好好算下来,学习web前端已有半个月了,这半个月来主要学习的是HTML和CSS部分,期间有困惑,也有解决困惑时的快感,所以想把这段时间感受到的一些东西记下来,因为内容比较杂,所以干脆叫随 ...
- mybatis入门基础(六)----高级映射(一对一,一对多,多对多)
一:订单商品数据模型 1.数据库执行脚本 创建数据库表代码: CREATE TABLE items ( id INT NOT NULL AUTO_INCREMENT, itemsname ) NOT ...
- N[开源].NET CORE与MySql更配, MySqlSugar ORM框架 3.x
MySqlSugar 3.X API 作为支持.NET CORE 为数不多的ORM之一,除了具有优越的性能外,还拥有强大的功能,不只是满足你的增,删,查和改.实质上拥有更多你想像不到的功能,当你需要实 ...
- 初学Python遇到的问题一二
这篇文章只是学Python最最最基础的部分知识,如果你已经有过python经验,哪怕就一点点经验,或许你都遇到过,但相信这些问题对你来说早已不算问题了,所以请跳过吧,用你的时间去学习更多其他的知识就好 ...
- AngularJS----基本操作
之前的学习基本了解了AngularJS的常用方法,下来就继续学习吧. 创建自定义的指令 除了内置指令,我们可以创建自定义指令.通过.directive函数来添加. <div change-dat ...
- GridView的使用
首先,gridview是封装好的,直接在设计界面使用,基本不需要写代码: 一.绑定数据源 GridView最好与LinQDatasourse配合使用,相匹配绑定数据: 二.样式控制 1.自动套用样式 ...
- ASP.NET Core开发-Docker部署运行
ASP.NET Core开发Docker部署,.NET Core支持Docker 部署运行.我们将ASP.NET Core 部署在Docker 上运行. 大家可能都见识过Docker ,今天我们就详细 ...
- C# 之 DataReader 和 DataSet 的区别
本文转载自:http://www.cnblogs.com/xinaixia/p/4920630.html 1. 获取数据的方式[1]DataReader 为在线操作数据, DataReader会一直占 ...