现在的位置: 首页 > 综合 > 正文

B-spline , deBoor算法实现

2013年10月10日 ⁄ 综合 ⁄ 共 2458字 ⁄ 字号 评论关闭

参考:

http://blog.csdn.net/tuqu/article/details/4749586

http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/

http://en.wikipedia.org/wiki/De_Boor_algorithm

tuqu的就是翻译Dr. C. -K的文章加上部分个人理解

实现deBoor算法

http://www.91r.net/ask/14258839.html  ,这个实现作者完全没验证!!!不靠谱

相对靠谱的实现(根据wekipedia实现的)  hi3x10.wordpress.com/2009/10/18/de-boor-algorithm-in-c

http://bbs.csdn.net/topics/380072374 (作者很粗暴就把算法贴出来,没做什么描述)


我是根据Dr. C.-K的文章来实现的,但是却出现了问题。

举例:

假设 6 个控制点 ,10 个节点 [0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0],3 次曲线 . 我要插入的u值分别为 [0.15,0.25,0.35,0.45,0.55,0.65,0.75,0.85,0.95].

当 u=0.75, 其落在了[U6,U7)节点空间, 按照hi3x10.wordpress.com/2009/10/18/de-boor-algorithm-in-c

的写法,将返回ctrlPoints[6],但是已经超出数组范围了!!!同理Dr. C. -K的deBoor算法也是如此,若s=0,则i=k时也超出了控制点数组Pi范围了。

而在WikiPedia上也只给出了原理,没说明l(即u所在区间)如何计算。

那么要么是我设置u出现了问题,要么是计算i(chi3x10用i表示,而Dr. C. -K用k表示)就不对,哪里出错了呢?

也许控制点应该用u所在Ui对应的控制点P,比如U6对应最大的控制点P5,而不是P6.

昨天思考了下,觉得根据B-Spline曲线定义,确实不可能超出控制点范围,所以实现程序时忽略超出范围的控制点即可. 比如u=0.75以及之后的u计算就要全部忽略。

同时,对比了C.-K的实现与wikiPedia的描述,发现其实两者基本一致(就1点不同),C.-K做得更完整,即插入值时要考虑原始节点(即m=n+p+1中的m+1个节点)的重复度。

不过两篇文章实现都没管插入节点如何设计的问题。

因为按照我遇到的问题,插入节点如果落在了[Uk,Uk+1),则可知

曲线次数<=k<=最后的控制点index。

按照算法,k<曲线次数就无法递归下去,而k大于最后控制点index就没有意义。

所以设计插入节点值时也得考虑下。

附上Dr. C. -K的de Boor算法

Input: a value u
Output: the point on the curve, C(u)

If u lies in [uk,uk+1) andu !=uk, leth =p (i.e., insertingup times) ands = 0;
If u = uk and uk is a knot of multiplicitys, leth =p - s (i.e., insertingup - s times);
Copy the affected control points Pk-s,
P
k-s-1, Pk-s-2, ...,Pk-p+1 andPk-p to a new array and rename them asPk-s,0,Pk-s-1,0,Pk-s-2,0,
...,Pk-p+1,0;

forr := 1 tohdo

    fori := k-p+rtok-sdo
      begin
        Let ai,r = (u - ui) / (ui+p-r+1 -ui )
        Let Pi,r = (1 - ai,r)Pi-1,r-1 +ai,rPi,r-1

      end

Pk-s,p-s is the point C(u).

问题:

C. -K在文章说到:if a knot u is insertedrepeatedly so that its multiplicity isp, the last generated new control point isthe point on the curve that corresponds tou.

但是Clamped曲线要求前后P+1个节点相等,P0=P1=..=Pp=u1 , Pm=Pm-1=..=Pm-p-1=u2。那我设计初始knot span时,如果u值等于U0=U1=U2是否有影响?因为如果U0=U1..=Up,那么我要插入的次数是 曲线次数P-u所在区间已有的重复度(即P+1次)=-1,即不插入。

另外,C. -k的算法里,如果k=0(此时曲线是C.-k称为的open曲线,其他人可能称为floating曲线),那如何计算P0,p-s?以为P0,p-s需要P-1,p-s才行,我该跳过还是该直接等于P0,r-1??这个问题同样适用于wikiPedia上deBoor算法的描述。

2013/10/18, 根据网络上http://course.cug.edu.cn/21cn/%BC%C6%CB%E3%BB%FA%CD%BC%D0%CE%D1%A7/Chapter3/CG_Txt_3_021.htm

关于B-Spline de boor算法的实现(如何弄到,嘿嘿),我发现了自己的bug。实现后完整地画出了B-Spline曲线(按照Dr. C. -K文章实现de boor是OK的)。

说实话,Xcode上debug相当痛苦啊。

目前网络上发现的中国教科书实现的算法都没有考虑u所在knot span已有的重复度。

同时考虑到中国这里知识共享的问题,我把实现的代码分享出来。部分代码有点傻,没有优化过,请需要的人自己优化。

免责声明:这段代码是利用Dr. C.-K的文章实现的,仅作为学习、交流使用,其他方面本人概不负责。

实现环境:

2013/10/18,Xcode4.6.1,OS X Mountain Lion,English

项目创建利用了Cocos2d2.1版

链接地址:http://pan.baidu.com/s/1BXi7R

抱歉!评论已关闭.