目录
1、把曲线离散成点
1.1按数量离散
1.2按长度离散
1.3按弦高离散
2、由点合成曲线
2.1B样条插值
2.2B样条近似
1、把曲线离散成点
计算机图形学中绘制曲线,无论是绘制参数曲线还是非参数曲线,都需要先将参数曲线进行离散化,通过离散化得到一组离散化的点集,然后再将点集发送给图形渲染管线进行处理,最终生成我们想要的曲线。
OpenCASCADE中提供了GCPnts包。利用GCPnts包中提供的类,我们可以很方便的将三维曲线进行离散化。
1.1按数量离散
#include <Geom_CylindricalSurface.hxx>#include <gp_Ax3.hxx>#include <GeomAPI_Interpolate.hxx>#include <BRepAdaptor_Curve.hxx>#include <BRepBuilderAPI_MakeEdge.hxx>#include <Geom2d_TrimmedCurve.hxx>#include <GCE2d_MakeSegment.hxx>#include <GeomAPI_PointsToBSpline.hxx>#include <BRepBuilderAPI_MakeFace.hxx>#include <GC_MakeCircle.hxx>#include <BRepBuilderAPI_MakeWire.hxx>#include <BRepOffsetAPI_MakePipe.hxx>#include <GC_MakeArcOfCircle.hxx>#include <BRepAlgoAPI_Fuse.hxx>#include <gp_GTrsf.hxx>#include <BRepBuilderAPI_MakeVertex.hxx>#include"Viewer.h"#include <BRepAdaptor_CompCurve.hxx>#include <GCPnts_UniformAbscissa.hxx>int main(int argc, char* argv[]){gp_Dir Z(0.0, 0.0, 1.0);gp_Pnt center(0, 0, 0.0);gp_Pnt xr(0.5, 0, 0.0);gp_Pnt yr(0.0, 1.0, 0.0);gp_Pnt zr(0.0, 0.0, 7.0);gp_Ax2 wb(center, Z);gp_Circ wbcircle(wb, 0.125 / 2);TopoDS_Edge wbe = BRepBuilderAPI_MakeEdge(wbcircle);TopoDS_Wire te = BRepBuilderAPI_MakeWire(wbe);BRepAdaptor_CompCurve compCurve(te);GCPnts_UniformAbscissa uniAbs(compCurve, 100, -1);gp_Pnt p;Viewer vout(50, 50, 500, 500);vout << te;if (uniAbs.IsDone()){for (Standard_Integer i = 1; i <= uniAbs.NbPoints(); ++i){Standard_Real u = uniAbs.Parameter(i);compCurve.D0(u, p);//获取每个离散点TopoDS_Vertex verti = BRepBuilderAPI_MakeVertex(p);vout << verti;}}vout.StartMessageLoop();return 0;}

1.2按长度离散
#include <Geom_CylindricalSurface.hxx>#include <gp_Ax3.hxx>#include <GeomAPI_Interpolate.hxx>#include <BRepAdaptor_Curve.hxx>#include <BRepBuilderAPI_MakeEdge.hxx>#include <Geom2d_TrimmedCurve.hxx>#include <GCE2d_MakeSegment.hxx>#include <GeomAPI_PointsToBSpline.hxx>#include <BRepBuilderAPI_MakeFace.hxx>#include <GC_MakeCircle.hxx>#include <BRepBuilderAPI_MakeWire.hxx>#include <BRepOffsetAPI_MakePipe.hxx>#include <GC_MakeArcOfCircle.hxx>#include <BRepAlgoAPI_Fuse.hxx>#include <gp_GTrsf.hxx>#include <BRepBuilderAPI_MakeVertex.hxx>#include"Viewer.h"#include <BRepAdaptor_CompCurve.hxx>#include <GCPnts_UniformAbscissa.hxx>int main(int argc, char* argv[]){gp_Dir Z(0.0, 0.0, 1.0);gp_Pnt center(0, 0, 0.0);gp_Pnt xr(0.5, 0, 0.0);gp_Pnt yr(0.0, 1.0, 0.0);gp_Pnt zr(0.0, 0.0, 7.0);gp_Ax2 wb(center, Z);gp_Circ wbcircle(wb, 0.125 / 2);TopoDS_Edge wbe = BRepBuilderAPI_MakeEdge(wbcircle);TopoDS_Wire te = BRepBuilderAPI_MakeWire(wbe);BRepAdaptor_CompCurve compCurve(te);GCPnts_UniformAbscissa uniAbs;uniAbs.Initialize(compCurve, 0.05, -1);gp_Pnt p;Viewer vout(50, 50, 500, 500);vout << te;if (uniAbs.IsDone()){for (Standard_Integer i = 1; i <= uniAbs.NbPoints(); ++i){Standard_Real u = uniAbs.Parameter(i);compCurve.D0(u, p);//获取每个离散点TopoDS_Vertex verti = BRepBuilderAPI_MakeVertex(p);vout << verti;}}vout.StartMessageLoop();return 0;}

1.3按弦高离散
#include <Geom_CylindricalSurface.hxx>#include <gp_Ax3.hxx>#include <GeomAPI_Interpolate.hxx>#include <BRepAdaptor_Curve.hxx>#include <BRepBuilderAPI_MakeEdge.hxx>#include <Geom2d_TrimmedCurve.hxx>#include <GCE2d_MakeSegment.hxx>#include <GeomAPI_PointsToBSpline.hxx>#include <BRepBuilderAPI_MakeFace.hxx>#include <GC_MakeCircle.hxx>#include <BRepBuilderAPI_MakeWire.hxx>#include <BRepOffsetAPI_MakePipe.hxx>#include <GC_MakeArcOfCircle.hxx>#include <BRepAlgoAPI_Fuse.hxx>#include <GCPnts_QuasiUniformDeflection.hxx>#include <BRepBuilderAPI_MakeVertex.hxx>#include"Viewer.h"#include <BRepAdaptor_CompCurve.hxx>#include <GCPnts_UniformAbscissa.hxx>int main(int argc, char* argv[]){gp_Dir Z(0.0, 0.0, 1.0);gp_Pnt center(0, 0, 0.0);gp_Pnt xr(0.5, 0, 0.0);gp_Pnt yr(0.0, 1.0, 0.0);gp_Pnt zr(0.0, 0.0, 7.0);gp_Ax2 wb(center, Z);gp_Circ wbcircle(wb, 0.125 / 2);TopoDS_Edge wbe = BRepBuilderAPI_MakeEdge(wbcircle);TopoDS_Wire te = BRepBuilderAPI_MakeWire(wbe);BRepAdaptor_CompCurve compCurve(te);GCPnts_QuasiUniformDeflection quasiUniDef;quasiUniDef.Initialize(compCurve, 0.08, GeomAbs_C0);gp_Pnt p;Viewer vout(50, 50, 500, 500);vout << te;if (quasiUniDef.IsDone()){for (Standard_Integer i = 1; i <= quasiUniDef.NbPoints(); ++i){p=quasiUniDef.Value(i);//获取每个离散点TopoDS_Vertex verti = BRepBuilderAPI_MakeVertex(p);vout << verti;}}vout.StartMessageLoop();return 0;}

2、由点合成曲线
曲线曲面拟合Curve and Surface Fitting的方式可以分为两类:插值interpolation和逼近approximation。采用插值的方式时,所创建的曲线或曲面必须精确地满足所给的数据条件,例如曲线通过所给的插值点。采用逼近的方式时,创建的曲线或曲面不必精确地满足所给的数据条件,只要在一定的误差范围内接近即可。
2.1B样条插值
#include <Geom_CylindricalSurface.hxx>
#include <gp_Ax3.hxx>
#include <GeomAPI_Interpolate.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <Geom2d_TrimmedCurve.hxx>
#include <GCE2d_MakeSegment.hxx>
#include <GeomAPI_PointsToBSpline.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <GC_MakeCircle.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <BRepOffsetAPI_MakePipe.hxx>
#include <GC_MakeArcOfCircle.hxx>
#include <BRepAlgoAPI_Fuse.hxx>
#include <GCPnts_QuasiUniformDeflection.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx>
#include"Viewer.h"
#include <BRepAdaptor_CompCurve.hxx>
#include <GeomTools.hxx>
int main(int argc, char* argv[])
{Handle(TColgp_HArray1OfPnt) aPoints = new TColgp_HArray1OfPnt(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());aInterpolater.Perform();aBSplineCurve = aInterpolater.Curve();//std::cout << "ok";TopoDS_Edge s = BRepBuilderAPI_MakeEdge(aBSplineCurve);Viewer vout(50, 50, 500, 500);vout << s;vout << BRepBuilderAPI_MakeVertex(aPoints->Value(1));vout << BRepBuilderAPI_MakeVertex(aPoints->Value(2));vout << BRepBuilderAPI_MakeVertex(aPoints->Value(3));vout.StartMessageLoop();return 0;
}

2.2B样条近似
#include <Geom_CylindricalSurface.hxx>#include <gp_Ax3.hxx>#include <GeomAPI_Interpolate.hxx>#include <BRepAdaptor_Curve.hxx>#include <BRepBuilderAPI_MakeEdge.hxx>#include <Geom2d_TrimmedCurve.hxx>#include <GCE2d_MakeSegment.hxx>#include <GeomAPI_PointsToBSpline.hxx>#include <BRepBuilderAPI_MakeFace.hxx>#include <GC_MakeCircle.hxx>#include <BRepBuilderAPI_MakeWire.hxx>#include <BRepOffsetAPI_MakePipe.hxx>#include <GC_MakeArcOfCircle.hxx>#include <BRepAlgoAPI_Fuse.hxx>#include <GCPnts_QuasiUniformDeflection.hxx>#include <BRepBuilderAPI_MakeVertex.hxx>#include"Viewer.h"#include <BRepAdaptor_CompCurve.hxx>#include <GeomTools.hxx>int main(int argc, char* argv[]){Handle(TColgp_HArray1OfPnt) aPoints = new TColgp_HArray1OfPnt(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_PointsToBSpline Approx(aPoints->Array1());Handle(Geom_BSplineCurve) K = Approx.Curve();TopoDS_Edge s = BRepBuilderAPI_MakeEdge(K);Viewer vout(50, 50, 500, 500);vout << s;vout << BRepBuilderAPI_MakeVertex(aPoints->Value(1));vout << BRepBuilderAPI_MakeVertex(aPoints->Value(2));vout << BRepBuilderAPI_MakeVertex(aPoints->Value(3));vout.StartMessageLoop();return 0;}
