OPEN CASCADE BSpline Curve Interpolation
OPEN CASCADE BSpline Curve Interpolation
Abstract. Global curve interpolation to point data is a way to construct curves. The paper focus on the interpolate algorithm in OPEN CASCADE, and give a simple example to demonstrate the usage of the GeomAPI_Interpolate class.
Key Words. Interpolate, NURBS, BSpline, OPEN CASCADE
1.Introduction
曲线曲面拟合Curve and Surface Fitting的方式可以分为两类:插值interpolation和逼近approximation。采用插值的方式时,所创建的曲线或曲面必须精确地满足所给的数据条件,例如曲线通过所给的插值点。采用逼近的方式时,创建的曲线或曲面不必精确地满足所给的数据条件,只要在一定的误差范围内接近即可,如下图所示:
Figure 1.1 A curve interpolating five points and end derivatives(The NURBS Book)
Figure 1.2 A curve approximating points(The NURBS Book)
本文先简要介绍B样条插值的原理,再结合OPEN CASCADE源码说明如何对给定点插值B样条曲线及OPEN CASCADE中插值曲线的一些注意事项。
2.Global Interpolation
假设给定一组数据点{Qk},k=0,1,…n,我们想要用一条p次非有理B样条曲线插值于这些点。如果我们为每个点Qk指定了一个参数值uk,并且选定了一个合适的节点矢量U,我们就可以建立一个系数矩阵为(n+1)x(n+1)的线性方程组:
n+1个控制点Pi是未知量。剩下的问题是如何确定Qk对应的参数值uk及节点矢量U,这将影响到曲线的形状和参数化。常见的选取uk的方法有均匀参数化法、弦长参数化法和向心参数化法。
2.1 Equally Spaced 均匀参数法
假设参数限定在[0,1]范围内,那么
当参数范围为[a,b]时,
均匀参数化法是最简单的构造参数的方法,但是不推荐采用这种方法,因为当数据点分布步均匀时,会产生很奇怪的形状,如打圈自交。
Figure 2.1 B-Spline curve interpolation with the uniformly spaced method[1]
2.2 Chord Length 弦长参数法
令d为总弦长,且把参数范围限定在[0,1]之间,则:
这是最常用的方法,并且一般用它就足够了,考虑到弦长参数化接近曲线的均匀参数化,在这种意义下,它给出了曲线的一个“好”的参数化。
2.3 Centripetal Method 向心参数法
这是一个更新的方法,当数据点急转弯变化时,这个方法能得到比弦长参数化更好的结果。
3.BSpline Interpolation in OPEN CASCADE
OPEN CASCADE对曲线的插值是通过GeomAPI包中的GeomAPI_Interpolate实现的。由其代码注释可知,这个类的功能是可以对一系列点进行插值得到C2连续的B样条曲线,当对插值点处的切矢不作要求时。对点直接插值的构造函数为:
GeomAPI_Interpolate (const Handle< TColgp_HArray1OfPnt > &Points, const Standard_Boolean PeriodicFlag, const Standard_Real Tolerance)
其中参数Points为插值点,PeriodicFlag为是否周期曲线,Tolerance是对插值点进行检查用的容差。Tolerance容易产生误解,根据插值曲线的定义,插值曲线是要求通过插值点的,所以不存在插值得到的曲线和插值点之间的容差。
经过查看OPEN CASCADE中插值曲线的源码,可以得出对曲线进行插值的步骤如下:
v 检查是否有重复的插值点CheckPoints;
v 生成参数BuildParameters;
v 使用BSplCLib::Interpolate()进行插值;
v 根据参数及次数生成系数矩阵,再结合插值点,对系数矩阵和插值点组成的方程组进行求解。
检查插值点代码如下:
static Standard_Boolean CheckPoints(const TColgp_Array1OfPnt& PointArray,
const Standard_Real Tolerance)
{
Standard_Integer ii ;
Standard_Real tolerance_squared = Tolerance * Tolerance,
distance_squared ;
Standard_Boolean result = Standard_True ;
for (ii = PointArray.Lower() ; result && ii < PointArray.Upper() ; ii++) {
distance_squared =
PointArray.Value(ii).SquareDistance(PointArray.Value(ii+)) ;
result = (distance_squared >= tolerance_squared) ;
}
return result ; }
由上述代码可知,Tolerance主要是用于检查插值点是否在容差范围内有重合现象。生成参数代码如下:
static void BuildParameters(const Standard_Boolean PeriodicFlag,
const TColgp_Array1OfPnt& PointsArray,
Handle(TColStd_HArray1OfReal)& ParametersPtr)
{
Standard_Integer ii,
index ;
Standard_Real distance ;
Standard_Integer
num_parameters = PointsArray.Length() ;
if (PeriodicFlag) {
num_parameters += ;
}
ParametersPtr =
new TColStd_HArray1OfReal(,
num_parameters) ;
ParametersPtr->SetValue(,0.0e0) ;
index = ;
for (ii = PointsArray.Lower() ; ii < PointsArray.Upper() ; ii++) {
distance =
PointsArray.Value(ii).Distance(PointsArray.Value(ii+)) ;
ParametersPtr->SetValue(index,
ParametersPtr->Value(ii) + distance) ;
index += ;
}
if (PeriodicFlag) {
distance =
PointsArray.Value(PointsArray.Upper()).
Distance(PointsArray.Value(PointsArray.Lower())) ;
ParametersPtr->SetValue(index,
ParametersPtr->Value(ii) + distance) ;
}
}
由上述代码可知,OPEN CASCADE插值生成参数的方法如下:
不是上述三种常用方法的之一,和弦长参数化法类似,但是没有去除以总弦长。生成节点矢量之前为了得到曲线的次数,做了如下处理:
if (num_poles == && !myTangentRequest) {
degree = ;
}
else if (num_poles == && !myTangentRequest) {
degree = ;
num_distinct_knots = ;
}
else {
degree = ;
num_poles += ;
if (myTangentRequest)
for (ii = myTangentFlags->Lower() + ;
ii < myTangentFlags->Upper() ; ii++) {
if (myTangentFlags->Value(ii)) {
num_poles += ;
}
}
}
由上述代码可知,插值要求至少有两个插值点。当只有两个插值点时,插值曲线次数为1,即为直线;当有三个插值点且没有切矢的要求时,插值曲线次数为2次;当插值点数多于3个时,插值曲线次数为3。即对于多于三个点进行插值时,最高只能得到3次曲线,也即C2连续的曲线。进行B样条插值的代码如下:
void BSplCLib::Interpolate(const Standard_Integer Degree,
const TColStd_Array1OfReal& FlatKnots,
const TColStd_Array1OfReal& Parameters,
const TColStd_Array1OfInteger& ContactOrderArray,
const Standard_Integer ArrayDimension,
Standard_Real& Poles,
Standard_Integer& InversionProblem)
{
Standard_Integer ErrorCode,
UpperBandWidth,
LowerBandWidth ;
// Standard_Real *PolesArray = &Poles ;
math_Matrix InterpolationMatrix(, Parameters.Length(),
, * Degree + ) ;
ErrorCode =
BSplCLib::BuildBSpMatrix(Parameters,
ContactOrderArray,
FlatKnots,
Degree,
InterpolationMatrix,
UpperBandWidth,
LowerBandWidth) ;
if(ErrorCode)
Standard_OutOfRange::Raise("BSplCLib::Interpolate"); ErrorCode =
BSplCLib::FactorBandedMatrix(InterpolationMatrix,
UpperBandWidth,
LowerBandWidth,
InversionProblem) ;
if(ErrorCode)
Standard_OutOfRange::Raise("BSplCLib::Interpolate"); ErrorCode =
BSplCLib::SolveBandedSystem(InterpolationMatrix,
UpperBandWidth,
LowerBandWidth,
ArrayDimension,
Poles) ;
if(ErrorCode)
Standard_OutOfRange::Raise("BSplCLib::Interpolate");
}
先是根据参数及插值曲线次数生成系数矩阵,再对系数矩阵和插值点构成的方程组进行求解,计算出B样条曲线的控制顶点Poles。有了节点矢量,次数及控制顶点,B样条就确定下来了:
myCurve =
new Geom_BSplineCurve(poles,
myParameters->Array1(),
mults,
degree) ;
myIsDone = Standard_True ;
OPEN CASCADE提供的插值接口使用还是很简单的,如对已经知点进行插值,其用法如下:
int main(int argc, char* argv[])
{
Handle_TColgp_HArray1OfPnt aPoints = new TColgp_HArray1OfPnt aPoints(, );
Handle_Geom_BSplineCurve aBSplineCurve; aPoints.SetValue(, gp_Pnt(0.0, 0.0, 0.0));
aPoints.SetValue(, gp_Pnt(1.0, 1.0, 0.0));
aPoints.SetValue(, gp_Pnt(2.0, 6.0, 3.0)); GeomAPI_Interpolate aInterpolater(aPoints, Standard_False, Precision::Approximation()); if (aInterpolater.IsDone())
{
aBSplineCurve = aInterpolater.Curve(); GeomTools::Dump(aBSplineCurve, std::cout);
}
}
4.Conclusion
综上所述,对给定点进行B样条插值时,需要考虑参数值及节点矢量的选择。参数值和节点矢量确定后,剩下就是利用B样条基函数对给定点的参数计算得到的系数组成的线性方程进行求解。
在使用OPEN CASCADE的曲线插值类GeomAPI_Interpolate时,需要注间容差Tolerance是用来对插值点进行检查的,且插值得到的曲线最高只能是三次曲线。
5.Acknowledgments
首先,感谢cnblog提供了一个表现自己的舞台http://www.cppblog.com/eryar/,能在网上和世界连通,知道不是一个人在战斗。
其次,感谢OPEN CASCADE的开源分享,才得以学到几何造型相关的知识,比起直接啃国内教材来,学习效率不可同日而语。正如“Talk is cheap, show me the code”所说,将代码和书本结合起来学习时,收获更大。
最后,感谢国内外友人对我的肯定和鼓励,他们自强不息,激情创业的精神总是让人兴奋。
生活的理想就是为了理想的生活The ideal of life is to live for ideals!人生充满了起起落落,关键在于在顶端时尽情享受,在低谷时不失勇气。
6.References
1. Hongxin Zhang, Jieqing Feng. B-Spline Interpolation and Approximation. Zhejiang University. 2006-12-18. http://www.cad.zju.edu.cn/home/zhx/GM/009/00-bsia.pdf
2. Les Piegl, Wayne Tiller. The NURBS Book. Springer-Verlag. 1995
3. 赵罡, 穆国旺, 王拉柱译. 非均匀有理B样条. 清华大学出版社. 1995
4. 易大义, 陈道琦. 数值分析引论. 浙江大学出版社. 1998
PDF Version: OPEN CASCADE BSpline Curve Interpolation
OPEN CASCADE BSpline Curve Interpolation的更多相关文章
- Convert BSpline Curve to Arc Spline in OpenCASCADE
Convert BSpline Curve to Arc Spline in OpenCASCADE eryar@163.com Abstract. The paper based on OpenCA ...
- OpenCascade B-Spline Basis Function
OpenCascade B-Spline Basis Function eryar@163.com Abstract. B-splines are quite a bit more flexible ...
- Open CASCADE Technology: IGES Support
2015/6/4 Open CASCADE Technology: IGES Support http://www.opencascade.org/doc/occt6.7.0/overview/ht ...
- OpenCASCADE Conic to BSpline Curves-Circle
OpenCASCADE Conic to BSpline Curves-Circle eryar@163.com Abstract. The conic sections and circles pl ...
- OpenCASCADE Conic to BSpline Curves-Hyperbola
OpenCASCADE Conic to BSpline Curves-Hyperbola eryar@163.com Abstract. Rational Bezier Curve can repr ...
- OpenCASCADE Conic to BSpline Curves-Parabola
OpenCASCADE Conic to BSpline Curves-Parabola eryar@163.com Abstract. Rational Bezier Curve can repre ...
- Geometry Curve of OpenCascade BRep
Geometry Curve of OpenCascade BRep eryar@163.com 摘要Abstract:几何曲线是参数表示的曲线 ,在边界表示中其数据存在于BRep_TEdge中,BR ...
- B-spline Curves 学习之B样条曲线的导数(8)
Derivatives of a B-spline Curve 本博客转自前人的博客的翻译版本,前几章节是原来博主的翻译内容,但是后续章节博主不在提供翻译,后续章节我在完成相关的翻译学习. (原来博客 ...
- Render OpenCascade Geometry Curves in OpenSceneGraph
在OpenSceneGraph中绘制OpenCascade的曲线 Render OpenCascade Geometry Curves in OpenSceneGraph eryar@163.com ...
随机推荐
- 微信小程序火车票查询 直取12306数据
最终效果图: 样式丑哭了,我毕竟不是前端,宗旨就是练练手,体验微信小程序的开发,以最直接的方式获取12306数据查询火车票. 目录结构: search1是出发站列表,search2是目的站列表,命名没 ...
- 原生AJAX封装
var ajaxHelper = { /*1.0 浏览器兼容的方式创建异步对象*/ makeXHR: function () { //声明异步对象变量 var xmlHttp = false; //声 ...
- gulp-babel使用
各大浏览器厂商对es2015功能支持不完全,等到全部支持会等很长时间,如果现在使用es2015,可以选择babel一个将ES6/ES7写的代码转换为ES5代码的编译器. 我们选择使用gulp自动化编译 ...
- indexOf、instanceOf、typeOf、valueOf详解
1.indexOf() 该方法用来返回某个指定的字符串值在字符串中首次出现的位置. 语法:indexOf(searchvalue,fromindex);两个参数,参数一表示查询的字符串值,参数二可选表 ...
- 用ProxyFactoryBean创建AOP代理
Spring的Advisor是Pointcut和Advice的配置器,它是将Advice注入程序中Pointcut位置的代码.org.springframework.aop.support.Defau ...
- 有关DTCoreText无法加载网络图片及应用问题
至于DTCoreText是干嘛的,不清楚的同学自行网上脑补,这就不啰嗦了,只说一下其用法. 里面有三种控件供大家使用,DTAttributedTextView, DTAttributedLabel 和 ...
- *HDU3398 数学
String Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm ...
- 八大排序算法Java
目录(?)[-] 概述 插入排序直接插入排序Straight Insertion Sort 插入排序希尔排序Shells Sort 选择排序简单选择排序Simple Selection Sort 选择 ...
- ASP.Net WebForm温故知新学习笔记:二、ViewState与UpdatePanel探秘
开篇:经历了上一篇<aspx与服务器控件探秘>后,我们了解了aspx和服务器控件背后的故事.这篇我们开始走进WebForm状态保持的一大法宝—ViewState,对其刨根究底一下.然后,再 ...
- 再看Ajax
再回顾Ajax相关的内容,再次梳理学习还是很有必要的,尤其是实际的开发中,ajax更是必不可少,仔细学习以便避免不必要的错误. 文章导读: --1.使用XMLHttpRequest---------- ...