B样条

在数学的子学科数值分析里,B-样条是样条曲线一种特殊的表示形式。它是B-样条基曲线的线性组合。B-样条是贝兹(贝塞尔)曲线的一种一般化,可以进一步推广为非均匀有理B样条(NURBS),使得我们能给更多一般的几何体建造精确的模型。

常数B样条

常数B样条是最简单的样条。只定义在一个节点距离上,而且不是节点的函数。它只是不同节点段(knot span)的标志函数(indicator function)。

线性B样条

线性B样条定义在两个相邻的节点段上,在节点连续但不可微。

三次B样条

一个片断上的B样条的表达式可以写作:

其中Si是第i个B样条片断而P是一个控制点集,ik是局部控制点索引。控制点的集合会是的集合,其中是比重,当它增加时曲线会被拉向控制点,在减小时则把曲线远离该点。

片段的整个集合m-2条曲线()由m+1个控制点()定义,作为t上的一个B样条可以定义为

其中i是控制点数,t是取节点值的全局参数。这个表达式把B样条表示为B样条基函数的线性组合,这也是这个名称的原因。

有两类B样条-均匀和非均匀。非均匀B样条相邻控制点间的距离不一定要相等。一个一般的形式是区间随着插入控制点逐步变小到0。

关于插值与样条的介绍请看:http://www.cnblogs.com/WhyEngine/p/4020294.html

核心代码:

 1 void    YcBSpline::BuildWeights()
 2 {
 3     ClearWeights();
 4
 5     for (Yuint i = 0; i < 4; i++)
 6     {
 7         m_splineWeights[i] = (Yreal*)malloc((m_subD)*sizeof(Yreal));
 8         m_tangentWeights[i] = (Yreal*)malloc((m_subD)*sizeof(Yreal));
 9     }
10
11     Yreal u, u_2, u_3;
12     for (Yuint i = 0; i < m_subD; i++)
13     {
14         u = (float)i / m_subD;
15         u_2 = u * u;
16         u_3 = u_2 * u;
17
18         // 参见"游戏编程精粹1"P331
19         m_splineWeights[0][i] = (-1.0f*u_3 + 3.0f*u_2 - 3.0f*u + 1.0f)/6.0f;
20         m_splineWeights[1][i] = ( 3.0f*u_3 - 6.0f*u_2 + 0.0f*u + 4.0f)/6.0f;
21         m_splineWeights[2][i] = (-3.0f*u_3 + 3.0f*u_2 + 3.0f*u + 1.0f)/6.0f;
22         m_splineWeights[3][i] = ( 1.0f*u_3 + 0.0f*u_2 + 0.0f*u + 0.0f)/6.0f;
23
24         // 参见"游戏编程精粹1"P333
25         m_tangentWeights[0][i] = (-1.0f*u_2 + 2.0f*u - 1.0f)*0.5f;
26         m_tangentWeights[1][i] = ( 3.0f*u_2 - 4.0f*u + 0.0f)*0.5f;
27         m_tangentWeights[2][i] = (-3.0f*u_2 + 2.0f*u + 1.0f)*0.5f;
28         m_tangentWeights[3][i] = ( 1.0f*u_2 + 0.0f*u + 0.0f)*0.5f;
29     }
30 }

切图:

相关软件的下载地址为:http://files.cnblogs.com/WhyEngine/TestSpline.zip

最后要注意的是:B样条曲线不会经过其控制点。靠,我一直以为是经过的。因为B样条是我唯一在项目中使用过的。我用它来平滑游戏中角色刀光所划出的曲面,不过这种细节也没必要再去修改了。

时间: 2024-10-23 22:47:07

B样条的相关文章

样条之CatmullRom

所谓样条曲线是指给定一组控制点而得到一条曲线,曲线的大致形状由这些点予以控制,一般可分为插值样条和逼近样条两种,插值样条通常用于数字化绘图或动画的设计,逼近样条一般用来构造物体的表面.CatmullRom样条与上一节所讲的B样条很相似,不同在于CatmullRom样条的曲线会经过其每一个控制点. The centripetal Catmull–Rom is a subclass of cubic Hermite spline that extends the Catmull–Rom implem

薄板样条差值(Thin plate spline)Java实现

最近一个项目里面需要用到图像变形,看了一些论文,提到几乎所有的生物有关的形变都可以使用薄板样条差值来近似.于是乎,我在网上搜索了一下薄板样条差值的代码. http://elonen.iki.fi/code/tpsdemo/有tps的c++代码.这份代码倒是可以运行(要自己另外配置opengl和boost),但是demo里面只有一个3D版本的,2D的版本只写了一个接口,并没有写demo.而我这个项目又是用java写的.于是,自己依据c++的2D版本的代码改写出了一份java版本的代码,为了方便大家

样条参数与曲线长度间的互相求解

背景 在开发路径插件时,需要解决以下问题:获得路径上某一点到路径起点的曲线长度:给定曲线长度,返回路径上点的位置.路径是由三次样条(Spline)组成的,三次样条就是最高次数为 3 的一元多项式.设样条为 P(t) = f(t), 只要知道 t 就可以得到具体位置的坐标.一阶导等信息.设样条曲线长度为 s,那么要求的就是 t-s 和 s-t 的关系.不幸的是,曲线长度的计算没有解析解,只有数值方法.数值方法不适用于游戏中的时时运算,对性能影响太大.但是,如果事先对 s-t 或 t-s 曲线采样,

样条之埃尔米特(Hermite)

埃尔米特(Charles Hermite,1822—1901) 法国数学家.巴黎综合工科学校毕业.曾任法兰西学院.巴黎高等师范学校.巴黎大学教授.法兰西科学院院士.在函数论.高等代数.微分方程等方面都有重要发现.1858年利用椭圆函数首先得出五次方程的解.1873年证明了自然对数的底e的超越性.在现代数学各分支中以他姓氏命名的概念(表示某种对称性)很多,如“埃尔米特二次型”.“埃尔米特算子”等. 这种算法是由上一节讲的CatmullRom演变而成. 关于插值与样条的介绍请看:http://www

样条之抛物线(一元三点)插值函数

它是根据给定结点上的数值,用抛物插值计算指定插值点处的函数.一元三点插值算法是一种精度更高的插值算法,使用这种方法插值出来的曲线不像线性插值算法那样在分段点的地方出现折点,显得更为平滑.但它是使用二次函数来进行曲线的拟合,曲线中还是会有不平滑的情况. 关于插值与样条的介绍请看:http://www.cnblogs.com/WhyEngine/p/4020294.html 核心代码: /////////////////////////////////////////////////////////

样条之贝塞尔(Bezier)

我曾经发过两篇关于贝塞尔的文章:数学图形(1.47)贝塞尔(Bézier)曲线,数学图形之贝塞尔(Bézier)曲面.那是使用我自己定义的脚本语言生成贝塞尔图形.由于我自己定义的脚本语法功能有限,所以最多只能支持5次贝塞尔函数,而这里将实现N次. N阶贝塞尔曲线可如下推断: 给定点P0.P1.….Pn,其贝塞尔曲线即 看其公式需要先为之生成一套杨辉三角形数组. 关于插值与样条的介绍请看:http://www.cnblogs.com/WhyEngine/p/4020294.html .h文件 1

B样条基函数的定义及系数的意义

原文链接:http://blog.csdn.net/tuqu/article/details/5177405 贝塞尔基函数用作权重.B-样条基函数也一样:但更复杂.但是它有两条贝塞尔基函数所没有的特性,即(1)定义域被节点细分(subdivided): (2) 基函数不是在整个区间非零.实际上,每个B样条基函数在附近一个子区间非零,因此,B-样条基函数相当“局部”. 设U 是m + 1个非递减数的集合,u0 <= u2 <= u3 <= ... <= um.ui称为节点(knots

Bezier曲线绘制 B样条绘制

/*输入点的个数是可以手动改动的,此程序中输入点的最大值设置为. *同时,程序实现了键盘的交互,用来控制程序运行过程中的退出.重画等 */ #include<GL/glut.h> #include<stdlib.h> int W,H; //屏幕的大小 int N =-1; //贝赛尔曲线的幂次 GLfloat Bfunc[15]={0.0}; //Bernstein多项式的值的数组 GLfloat point[15][2]={0.0}; //存储控制点的坐标 void Init()

三次B样条基于型值点反求控制点

在计算机图形中经常要求根据已获得的型值点反求三次B样条,我们通常的方法是反求的控制点首末端点与型值点首末端点重合,然后相邻型值点作为最小B样条的一段.对型值点的参数化方法有:均匀参数化,积累弦长参数化和向心参数化.这里对向心参数化没有作深入讨论.均匀参数化主要是针对型值点之间的间距较为接近,如果相差悬殊往往获得B样条效果较差,容易出现尖点或自交.积累弦长参数化,可以反映数据点按弦长的分布情况,也更适合构造B样条或者非均匀有理B样条.具体可以参考相关论文.