# OPEN CASCADE BSpline Curve Interpolation

2015/11/13 20:07

### OPEN CASCADE BSpline Curve Interpolation

eryar@163.com

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

Figure 1.1 A curve interpolating five points and end derivatives(The NURBS Book)

Figure 1.2 A curve approximating points(The NURBS Book)

2.Global Interpolation

n+1个控制点Pi是未知量。剩下的问题是如何确定Qk对应的参数值uk及节点矢量U，这将影响到曲线的形状和参数化。常见的选取uk的方法有均匀参数化法、弦长参数化法和向心参数化法。

2.1 Equally Spaced 均匀参数法

Figure 2.1 B-Spline curve interpolation with the uniformly spaced method[1]

2.2 Chord Length 弦长参数法

2.3 Centripetal Method 向心参数法

GeomAPI_Interpolate (const Handle< TColgp_HArray1OfPnt > &Points, const Standard_Boolean PeriodicFlag, const Standard_Real Tolerance)

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+1)) ;
result = (distance_squared >= tolerance_squared) ;
}
return result ;

}

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 += 1 ;
}
ParametersPtr =
new TColStd_HArray1OfReal(1,
num_parameters) ;
ParametersPtr->SetValue(1,0.0e0) ;
index = 2 ;
for (ii = PointsArray.Lower() ; ii < PointsArray.Upper() ; ii++) {
distance =
PointsArray.Value(ii).Distance(PointsArray.Value(ii+1)) ;
ParametersPtr->SetValue(index,
ParametersPtr->Value(ii) + distance) ;
index += 1 ;
}
if (PeriodicFlag) {
distance =
PointsArray.Value(PointsArray.Upper()).
Distance(PointsArray.Value(PointsArray.Lower())) ;
ParametersPtr->SetValue(index,
ParametersPtr->Value(ii) + distance) ;
}
}

if (num_poles == 2 &&   !myTangentRequest)  {
degree = 1 ;
}
else if (num_poles == 3 && !myTangentRequest) {
degree = 2 ;
num_distinct_knots = 2 ;
}
else {
degree = 3 ;
num_poles += 2 ;
if (myTangentRequest)
for (ii = myTangentFlags->Lower() + 1 ;
ii < myTangentFlags->Upper() ; ii++) {
if (myTangentFlags->Value(ii)) {
num_poles += 1 ;
}
}
}

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(1, Parameters.Length(),
1, 2 * Degree + 1) ;
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");
}

myCurve =
new Geom_BSplineCurve(poles,
myParameters->Array1(),
mults,
degree) ;
myIsDone = Standard_True ;

int main(int argc, char* argv[])
{
Handle_TColgp_HArray1OfPnt aPoints = new TColgp_HArray1OfPnt aPoints(1, 3);
Handle_Geom_BSplineCurve aBSplineCurve;

aPoints.SetValue(1, gp_Pnt(0.0, 0.0, 0.0));
aPoints.SetValue(2, gp_Pnt(1.0, 1.0, 0.0));
aPoints.SetValue(3, 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

5.Acknowledgments

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

0
0 收藏

0 评论
0 收藏
0