目录
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;
}