Abstract. In modeling, it is often required to approximate or interpolate points to curves and surfaces. In interpolation, the process is complete when the curve or surface passes through all the points; in approximation, when it is as close to these points as possible. The paper is the translation of the OpenCASCADE Modeling Data user guide.
Key Words. Interpolation, Approximation, Fitting
1.Introduction
在几何造型中,经常会需要根据点去拟合(插值Interpolation或逼近Approximation)曲线曲面。插值要求拟合所得的曲线或曲面必须通过所有拟合点;而逼近要求拟合所得曲线或曲面尽可能地靠近全部拟合点。OpenCASCADE中提供了曲线曲面拟合的功能有:
v 对二维点进行二维B样条或Bezier曲线插值;
v 对二维点进行二维B样条或Bezier曲线逼近;
v 对三维点进行三维B样条或Bezier曲线或B样条曲面插值;
v 对三维点进行三维B样条或Bezier曲线或B样条曲面逼近;
程序中使用拟合功能有两种方式:
v 使用高级功能:提供简单的方法调用来获得拟合结果;
v 使用低级功能:专为想对拟合有更多控制的用户设计;
插值和逼近也是数值分析或计算方法中的主要内容。用B样条作为插值或逼近函数是数值分析中的一个具体方法。通过对OpenCASCADE中插值和逼近算法的学习,加深对一些算法,如最小二乘法,多元函数求极值等数学知识的理解。
本文主要是对OpenCASCADE的文档Modeling Data 中的插值和逼近部分进行翻译,并给出了使用其低级功能具体的代码示例。
2.Analysis of a set of points
包GProp中的类PEquation提供了对点集、点云数据进行分析的功能,可以用来验证在给定的精度范围内是否重合、共线或共面等,如果检测结果是,那么算法将计算出这些点的重合点、线或面。如果检测结果不是,则算法会计算出点集或点云的包围盒。
3.Basic Interpolation and Approximation
包Geom2dAPI和GeomAPI提供了拟合(逼近和插值)简单的方法。
v 2D Interpolation: 类Geom2dAPI_Interpolate可以用于生成一条通过一系列点的二维B样条曲线。如果需要,还可以设置点相应的切矢及参数来对插值曲线做进一步的约束。
v 3D Interpolation: 类GeomAPI_Interpolate可以用于生成一条通过一系列点的三维B样条曲线。如果需要,还可以设置点相应的切矢及参数来对插值曲线做进一步的约束。因为是高级功能,所以需要很少的代码就可以得到插值曲线,用法如下:
GeomAPI_Interpolate Interp(Points);
Handle_Geom_BSplineCurve C = Interp.Curve();
v 2D Approximation: 类Geom2dAPI_PointsToBSpline可以用于生成逼近一系列点的二维B样条曲线。你需要定义曲线次数范围,连续性和容差。容差值只是用来检查逼近点之间是不是有重合点,或者切矢是否太小。逼近曲线将会是C2连续或2次曲线,当有切矢约束时,将会得到C1连续的曲线。
v 3D Approximation:类GeomAPI_PointsToBSpline可以用于生成逼近一系列点的三维B样条曲线。你需要定义曲线次数范围,连续性和容差。容差值只是用来检查逼近点之间是不是有重合点,或者切矢是否太小。逼近曲线将会是C2连续或2次曲线,当有切矢约束时,将会得到C1连续的曲线。类的用法如下:
GeomAPI_PointsToBSpline Approx(Points, DegMin, DegMax, Continutity, Tol);
Handle_Geom_BSplineCurve K = Approx.Curve();
v Surface Approximation:类GeomAPI_PointsToBSplineSurface可以用于根据点集拟合B样条曲面。
4.Advanced Approximation
包AppDef和AppParCurves提供了低级的功能,允许对拟合有更多地控制。低级功能提供了如下函数接口API:
v 定义拟合切矢的规则,这些切矢有原点和极值;
v 根据各自参数平行地拟合一系列曲线;
v 光滑拟合:生成光顺(faired curve)的曲线。
注:包AppDef和AppParCurves中通过宏定义实现了一种类似多态的功能,但是程序调试不方便,导致一些类名没有看到声明文件,对程序的理解造成一些不便。
4.1 Approximation by multiple point constraints
包AppDef中提供了低级工具用于对带约束的点集进行Bezier或B样条曲线拟合。其中的功能有:
v 定义一组约束点,使用类AppDef_MultiPointConstraint;
v 定义一组约束线,使用类AppDef_MultiLine;
v 拟合Bezier曲线,使用类AppDef_Compute;
v 拟合B样条曲线,使用类AppDef_BSplineCompute;
v 定义变分标准Variational Criteria;
注:在类AppDef_Variational中可以看到Variational Optimization变分优化。对于工科出来的人来说,这些概念还真是有些陌生,还是学数学的人厉害!
其中类AppDef_MultiLine的用法也有点特别,通过文档中的图来理解下:
其中:Pi, Qi, Ri, ..., Si可以是二维点或三维点;
按组来定义,其中Pn, Qn, Rn, ..., Sn都是在类AppDef_MultiPointConstraint中定义;
P1, P2, .., Pn或Q, R,..., S的点系列用来拟合。
类AppDef_Compute用Bezier曲线来拟合点;
类AppDef_BSplineCompute用B样条曲线来拟合点;
注:需要仔细理解AppDef_MultiPointConstraint和AppDef_MultiLine的用法。
4.2 Example: How to approximate a curve with low-level tools
使用低级功能的过程可分为如下几步:
v 定义拟合点;
v 根据拟合点创建MultiLine;
v 使用AppDef_Compute或AppDef_BSplineCompute来拟合曲线;
下面给出使用低级功能的代码示例:
/* * Copyright (c) 2016 Shing Liu All Rights Reserved. * * File : main.cpp * Author : Shing Liu([email protected]) * Date : 2016-03-17 21:00 * Version : OpenCASCADE6.9.0 * * Description : test the low-level tools of approximation. */ #define WNT #include <TColgp_Array1OfPnt.hxx> #include <AppDef_MultiPointConstraint.hxx> #include <AppDef_MultiLine.hxx> #include <AppDef_Compute.hxx> #include <AppDef_BSplineCompute.hxx> #pragma comment(lib, "TKernel.lib") #pragma comment(lib, "TKMath.lib") #pragma comment(lib, "TKGeomBase.lib") void testBezierApprox() { TColgp_Array1OfPnt aPoints(1, 3); aPoints.SetValue(1, gp_Pnt(0.0, 0.0, 0.0)); aPoints.SetValue(2, gp_Pnt(1.0, 0.0, 0.0)); aPoints.SetValue(3, gp_Pnt(1.0, 1.0, 0.0)); AppDef_MultiLine aMultiLine(aPoints); AppDef_Compute aBezierApprox(aMultiLine); aBezierApprox.Value().Dump(std::cout); } void testBSplineApprox() { AppDef_MultiLine aMultiLine(3); AppDef_MultiPointConstraint aMPC1(2, 0); AppDef_MultiPointConstraint aMPC2(2, 0); AppDef_MultiPointConstraint aMPC3(2, 0); aMPC1.SetPoint(1, gp_Pnt(0.0, 0.0, 0.0)); aMPC1.SetPoint(2, gp_Pnt(0.0, 2.0, 0.0)); aMPC2.SetPoint(1, gp_Pnt(1.0, 0.0, 0.0)); aMPC2.SetPoint(2, gp_Pnt(1.0, 2.0, 0.0)); aMPC3.SetPoint(1, gp_Pnt(1.0, 1.0, 0.0)); aMPC3.SetPoint(2, gp_Pnt(1.0, 3.0, 1.0)); aMultiLine.SetValue(1, aMPC1); aMultiLine.SetValue(2, aMPC2); aMultiLine.SetValue(3, aMPC3); AppDef_BSplineCompute aBSplineApprox(aMultiLine); aBSplineApprox.Value().Dump(std::cout); } int main(int argc, char* argv[]) { testBezierApprox(); testBSplineApprox(); return 0; }
程序运行结果如下图所示:
5.Conclusion
关于点的插值和逼近是《数据逼近》或《数值分析》或《计算方法》书中关注的内容。从文档中可以看到包AppDef中的一些关键字:Gradient, BFGS, LeastSquare等,根据这些关键字可以看出OpenCASCADE中逼近使用的算法了。
通过使用AppDef_MultiPointConstraint及AppDef_MultiLine等低级接口,来理解拟合数据点输入及拟合结果的输出。进而去学习BFGS、LeastSquare等数学理论工具在实际中的应用。对于多元函数,梯度及BFGS等概念还好接受,对于变分法优化之类理论已经超出了工科数学的范围,不过结合实际去学习这些概念应该会更有效率。