Open CASCADE学习|按圆离散旋转体

旋转体是一个非常重要的概念,它涉及到三维空间中由二维曲线绕某一轴线旋转形成的立体形状。这种旋转体的形成过程,实际上是一个连续变化的动态过程,但在数学和几何学中,我们往往通过静态的方式来描述和研究它。

旋转体的基本特性包括其形状、大小、表面积和体积等。这些特性不仅取决于原始二维曲线的形状和大小,还受到旋转轴线位置和方向的影响。例如,一个圆绕其直径旋转会形成球体,而绕其切线旋转则会形成圆柱体。

将旋转体离散为一系列的圆(通常称为"截圆"或"横截面")是一种常用的近似方法,用于在数值计算、计算机图形学以及物理模拟中描述和分析旋转体的性质。这种方法的基本思想是将连续的旋转体划分为一系列离散的、平行的截面,每个截面都是一个圆。

需要注意的是,离散化的精度取决于截面间距的选择。较小的间距可以提高精度,但也会增加计算复杂性和存储需求。因此,在实际应用中,需要根据具体需求和资源限制来选择合适的离散化方案。

cpp 复制代码
#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_Transform.hxx>

#include"Viewer.h"

#include <BRepPrimAPI_MakeCylinder.hxx>
#include <BRepBuilderAPI_MakePolygon.hxx>
#include <BRep_Tool.hxx>
#include <TopoDS.hxx>
#include <BRepAlgoAPI_Cut.hxx>
#include <BRepAlgoAPI_Common.hxx>
#include <BRepAlgoAPI_Section.hxx>
#include <BRepPrimAPI_MakePrism.hxx>
#include <GC_MakeSegment.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <ShapeUpgrade_UnifySameDomain.hxx>
#include <BRepTools_WireExplorer.hxx>
#include <GeomFill_TrihedronLaw.hxx>
#include <GeomFill_Frenet.hxx>
#include <GeomFill_CurveAndTrihedron.hxx>
#include <BRepFill_Edge3DLaw.hxx>
#include <BRepFill_SectionPlacement.hxx>
#include <ShapeUpgrade_RemoveLocations.hxx>
#include <BRepPrimAPI_MakeSphere.hxx>
#include <BRepPrimAPI_MakeRevol.hxx>
#include <BRepAdaptor_CompCurve.hxx>
#include <TopExp_Explorer.hxx>
#include <NCollection_Sequence.hxx>
TopoDS_Edge axis;
NCollection_Sequence<TopoDS_Edge> SplitShapebyaxis(TopoDS_Shape input, TopoDS_Edge cutaxis)
{
    Standard_Real startParam(0.), endParam(0.);
    Handle(Geom_Curve) c = BRep_Tool::Curve(cutaxis, startParam, endParam);//得到底层曲线
    Standard_Real step = (endParam - startParam) / 100;
    TColgp_HArray1OfPnt Points(1, 101);
    for (int i = 0; i < 101; i++) 
    {
        Points[i + 1] = c->Value(startParam + i * step);
    }
    gp_Vec dir(Points[1], Points[101]);
    NCollection_Sequence<TopoDS_Edge> edgeall;
    for (int i = 2; i < 100; i++)
    {
        gp_Pln cutplane(Points[i], dir);
        TopoDS_Face cf = BRepBuilderAPI_MakeFace(cutplane);
        // 进行布尔运算
        BRepAlgoAPI_Section section(input, cf, Standard_False);
        section.ComputePCurveOn1(Standard_True);
        section.Approximation(Standard_False);
        section.Build();
        TopExp_Explorer anExp(section.Shape(), TopAbs_EDGE);
        int j = 0;
        for (; anExp.More(); anExp.Next())
        {
            TopoDS_Edge anEdge = TopoDS::Edge(anExp.Current());
            edgeall.Append(anEdge);
            j++;
        }
        //std::cout << "j=" << j << std::endl;
    }
    return edgeall;
}
TopoDS_Edge createHelix(const Standard_Real HelixRadius, const Standard_Real HelixAngle, const Standard_Real HelixLength)
{
    Standard_Real u0 = 0.0;
    Standard_Real u1 = 2 * M_PI;
    Standard_Real v0 = 0.0;
    Standard_Real v1 = HelixLength;
    double uInter = (u1 - u0) / 1000;
    double vInter = (v1 - v0) / 1000;
    TColgp_HArray1OfPnt Points(1, 1001);
    Handle(Geom_CylindricalSurface) aCylinder = new Geom_CylindricalSurface(gp::XOY(), HelixRadius);
    double u;
    double v;
    //生成点
    for (int i = 0; i < 1001; i++) {
        u = i * vInter * tan(HelixAngle) / HelixRadius;
        v = i * vInter;
        Points[i + 1] = aCylinder->Value(u, v);
    }
    GeomAPI_PointsToBSpline Approx(Points);
    Handle_Geom_BSplineCurve K = Approx.Curve();
    TopoDS_Edge aHelixEdge = BRepBuilderAPI_MakeEdge(K);
    return aHelixEdge;
}

TopoDS_Shape createGrindingwheel2()
{
    Standard_Real Line1_angle = 280 * M_PI / 180;
    Standard_Real Line1_length = 0.5031;
    Standard_Real Line2_angle = 236 * M_PI / 180;
    Standard_Real Line2_length = 0.5925;
    Standard_Real Arc1_r = 0.112;
    Standard_Real Arc1_angle = (180 + 10 + 50) * M_PI / 180;
    gp_Pnt Line1_p1(-0.6822 / 2, 0, 0);
    gp_Pnt Line2_p1(0.6822 / 2, 0, 0);
    gp_Lin Line1(Line1_p1, gp_Dir(cos(Line1_angle), sin(Line1_angle), 0.));
    gp_Lin Line2(Line2_p1, gp_Dir(cos(Line2_angle), sin(Line2_angle), 0.));
    Handle(Geom_TrimmedCurve) L1 = GC_MakeSegment(Line1, 0., Line1_length);
    TopoDS_Edge L1e = BRepBuilderAPI_MakeEdge(L1);
    Handle(Geom_TrimmedCurve) L2 = GC_MakeSegment(Line2, 0., Line2_length);
    TopoDS_Edge L2e = BRepBuilderAPI_MakeEdge(L2);
    gp_Pnt l1end = L1->EndPoint();
    gp_Pnt l2end = L2->EndPoint();
    gp_Lin Line1v(l1end, gp_Dir(cos(Line1_angle + M_PI_2), sin(Line1_angle + M_PI_2), 0.));
    gp_Lin2d Line2v(gp_Pnt2d(l2end.X(), l2end.Y()), gp_Dir2d(cos(Line2_angle - M_PI_2), sin(Line2_angle - M_PI_2)));
    gp_Lin Line2v3d(l2end, gp_Dir(cos(Line2_angle - M_PI_2), sin(Line2_angle - M_PI_2), 0.));
    Handle(Geom_TrimmedCurve) L1v = GC_MakeSegment(Line1v, 0., Arc1_r);
    gp_Pnt l1vend = L1v->EndPoint();
    gp_Circ c1(gp_Ax2(l1vend, gp_Dir(0, 0, 1)), Arc1_r);
    Handle(Geom_TrimmedCurve) c1c = GC_MakeArcOfCircle(c1, l1end, Arc1_angle, 1);
    gp_Pnt c1end = c1c->EndPoint();
    gp_Lin2d Line3(gp_Pnt2d(c1end.X(), c1end.Y()), gp_Dir2d(l2end.X() - c1end.X(), l2end.Y() - c1end.Y()));
    gp_Lin2d Line3v = Line3.Normal(gp_Pnt2d((l2end.X() + c1end.X()) / 2, (l2end.Y() + c1end.Y()) / 2));
    IntAna2d_AnaIntersection aIntAna;
    aIntAna.Perform(Line2v, Line3v);
    IntAna2d_IntPoint aIntPoint = aIntAna.Point(1);
    gp_Pnt o2(aIntPoint.Value().X(), aIntPoint.Value().Y(), 0.);
    Handle(Geom_TrimmedCurve) L2v = GC_MakeSegment(Line2v3d, l2end, o2);
    Standard_Real r2 = L2v->LastParameter();
    gp_Circ c2(gp_Ax2(o2, gp_Dir(0, 0, 1)), r2);
    Handle(Geom_TrimmedCurve) c2c = GC_MakeArcOfCircle(c2, c1end, l2end, 0);
    gp_Pnt c2low = c2c->Value(M_PI_2);

    TopoDS_Edge c1ce = BRepBuilderAPI_MakeEdge(c1c);
    TopoDS_Edge L1ev = BRepBuilderAPI_MakeEdge(L1v);
    TopoDS_Edge c2ce = BRepBuilderAPI_MakeEdge(c2c);

    gp_Pnt Line1_up(-0.9832 / 2, 5, 0);
    gp_Pnt Line2_up(0.9832 / 2, 5, 0);
    TopoDS_Edge anEdge1 = BRepBuilderAPI_MakeEdge(Line1_p1, Line1_up);
    TopoDS_Edge anEdge2 = BRepBuilderAPI_MakeEdge(Line1_up, Line2_up);
    TopoDS_Edge anEdge3 = BRepBuilderAPI_MakeEdge(Line2_up, Line2_p1);
    TopTools_ListOfShape listEdge;
    listEdge.Append(anEdge1);
    listEdge.Append(anEdge2);
    listEdge.Append(anEdge3);
    listEdge.Append(L1e);
    listEdge.Append(c1ce);
    listEdge.Append(c2ce);
    listEdge.Append(L2e);
    BRepBuilderAPI_MakeWire mw;
    mw.Add(listEdge);
    mw.Build();
    TopoDS_Edge tmpAxis = BRepBuilderAPI_MakeEdge(gp_Pnt(-0.9832 / 2, 5, 0), gp_Pnt(0.9832 / 2, 5, 0));
    TopoDS_Shape gwheel = BRepPrimAPI_MakeRevol(mw, gp_Ax1(gp_Pnt(0, 5, 0), gp_Dir(1, 0, 0)), 2 * M_PI);
    //平移到最低点与原点重合
    gp_Trsf theTransformation1;
    gp_Vec theVectorOfTranslation1(-c2low.X(), -c2low.Y(), 0.);
    theTransformation1.SetTranslation(theVectorOfTranslation1);
    //往上平移芯厚一半的距离
    gp_Trsf theTransformation2;
    gp_Vec theVectorOfTranslation2(0., 0.125 / 2, 0.);
    theTransformation2.SetTranslation(theVectorOfTranslation2);
    //顺时针旋转90°,绕z轴
    gp_Trsf theTransformation3;
    gp_Ax1 axez = gp_Ax1(gp_Pnt(0, 0, 0), gp_Dir(0., 0., 1.));
    theTransformation3.SetRotation(axez, -90 * M_PI / 180);
    //顺时针旋转50°,绕x轴
    gp_Trsf theTransformation4;
    gp_Ax1 axex = gp_Ax1(gp_Pnt(0, 0, 0), gp_Dir(1., 0., 0.));
    theTransformation4.SetRotation(axex, -50 * M_PI / 180);
    //实施以上变换:对旋转体、对轴线
    BRepBuilderAPI_Transform myBRepTransformation(gwheel, theTransformation4 * theTransformation3 * theTransformation2* theTransformation1);
    TopoDS_Shape TransformedShape = myBRepTransformation.Shape();

    BRepBuilderAPI_Transform myBRepTransformation2(tmpAxis, theTransformation4 * theTransformation3 * theTransformation2 * theTransformation1);
    TopoDS_Shape initAxis = myBRepTransformation2.Shape();
    axis = TopoDS::Edge(initAxis);
    return TransformedShape;
}
TopoDS_Shape getShapeOnPosition(TopoDS_Shape myProfile, Handle(BRepFill_LocationLaw) myLoc, Standard_Real pos, Standard_Real a, Standard_Real b, gp_Trsf myTrsf)
{
    TopoDS_Shape myPos;
    Handle(GeomFill_LocationLaw) law;
    gp_Mat M;
    gp_Vec V;
    gp_Trsf fila;
    Standard_Real first, last;
    myLoc->Law(1)->GetDomain(first, last);
    Standard_Real px = (pos - a) / (b - a);
    myLoc->Law(1)->D0(px, M, V);
    fila.SetValues(M(1, 1), M(1, 2), M(1, 3), V.X(),
        M(2, 1), M(2, 2), M(2, 3), V.Y(),
        M(3, 1), M(3, 2), M(3, 3), V.Z());

    fila.Multiply(myTrsf);
    myPos = myProfile;
    TopLoc_Location LocPos(fila);
    if (!LocPos.IsIdentity()) {
        myPos = BRepBuilderAPI_Transform(myProfile, fila, Standard_True); //copy
    }
    ShapeUpgrade_RemoveLocations RemLoc;
    RemLoc.SetRemoveLevel(TopAbs_COMPOUND);
    RemLoc.Remove(myPos);
    myPos = RemLoc.GetResult();
    return myPos;
}
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_Edge xline = BRepBuilderAPI_MakeEdge(center, xr);
    TopoDS_Edge yline = BRepBuilderAPI_MakeEdge(center, yr);
    TopoDS_Edge zline = BRepBuilderAPI_MakeEdge(center, zr);
    //creat a profile of gringing wheel
    TopoDS_Shape gw = createGrindingwheel2();
    //creat a cylinder surface
    Standard_Real R = 0.306 / 2;
    Handle(Geom_CylindricalSurface) aCylinder = new Geom_CylindricalSurface(gp::XOY(), R);
    TopoDS_Shape cF = BRepBuilderAPI_MakeFace(aCylinder->Cylinder(), 0, 2 * M_PI, 0, 3.);

    TopoDS_Solid cys = BRepPrimAPI_MakeCylinder(gp::XOY(), R, 7);

    TopoDS_Edge aE = createHelix(R, M_PI / 4, 6.);
    TopoDS_Wire spine = BRepBuilderAPI_MakeWire(aE);


    TopoDS_Wire mySpine;
    TopoDS_Shape myProfile;
    TopoDS_Shape myShape;
    gp_Trsf myTrsf;
    Handle(BRepFill_LocationLaw) myLoc;
    Handle(TopTools_HArray2OfShape) mySections;
    Handle(TopTools_HArray2OfShape) myFaces;
    Handle(TopTools_HArray2OfShape) myEdges;
    TopTools_MapOfShape myReversedEdges;
    BRepFill_DataMapOfShapeHArray2OfShape myTapes;
    BRepFill_DataMapOfShapeHArray2OfShape myRails;
    Standard_Integer myCurIndexOfSectionEdge;
    TopoDS_Shape myFirst;
    TopoDS_Shape myLast;
    TopTools_DataMapOfShapeListOfShape myGenMap;
    Standard_Integer myDegmax;
    Standard_Integer mySegmax;
    GeomAbs_Shape myContinuity;
    GeomFill_Trihedron myMode;
    Standard_Boolean myForceApproxC1;
    Standard_Real myErrorOnSurf;

    mySections.Nullify();
    myFaces.Nullify();
    myEdges.Nullify();

    mySpine = spine;
    myProfile = gw;
    //myProfile = BRepPrimAPI_MakeSphere(gp_Pnt(0.306/2, 0., 0.),0.306/2);

    TopoDS_Shape TheProf;

    Handle(GeomFill_TrihedronLaw) TLaw;
    TLaw = new GeomFill_Frenet();
    Handle(GeomFill_CurveAndTrihedron) Loc = new (GeomFill_CurveAndTrihedron) (TLaw);
    myLoc = new (BRepFill_Edge3DLaw) (mySpine, Loc);
    if (myLoc->NbLaw() == 0) {
        return 0; // Degenerated case
    }
    myLoc->TransformInG0Law(); // Set into continuity

    BRepFill_SectionPlacement Place(myLoc, gw);
    myTrsf = Place.Transformation();

    TopLoc_Location Loc2(myTrsf), Loc1;
    Loc1 = gw.Location();
    TopoDS_Shape aux;
    TheProf = myProfile;
    TheProf.Location(Loc2.Multiplied(Loc1));

    // Construct First && Last Shape
    Handle(GeomFill_LocationLaw) law;

    gp_Mat M;
    gp_Vec V;
    gp_Trsf fila;
    Standard_Real first, last;
    myLoc->Law(1)->GetDomain(first, last);
    myLoc->Law(1)->D0(first, M, V);
    fila.SetValues(M(1, 1), M(1, 2), M(1, 3), V.X(),
        M(2, 1), M(2, 2), M(2, 3), V.Y(),
        M(3, 1), M(3, 2), M(3, 3), V.Z());

    fila.Multiply(myTrsf);
    TopLoc_Location LocFirst(fila);
    myFirst = myProfile;
    if (!LocFirst.IsIdentity()) {
        //myFirst.Location( LocFirst.Multiplied(myProfile.Location()) );
        myFirst = BRepBuilderAPI_Transform(myProfile, fila, Standard_True); //copy
    }

    ShapeUpgrade_RemoveLocations RemLoc;
    RemLoc.SetRemoveLevel(TopAbs_COMPOUND);
    RemLoc.Remove(myFirst);
    myFirst = RemLoc.GetResult();

    myLoc->Law(myLoc->NbLaw())->GetDomain(first, last);
    myLoc->Law(myLoc->NbLaw())->D0(last, M, V);
    //    try { // Not good, but there are no other means to test SetValues
    fila.SetValues(M(1, 1), M(1, 2), M(1, 3), V.X(),
        M(2, 1), M(2, 2), M(2, 3), V.Y(),
        M(3, 1), M(3, 2), M(3, 3), V.Z());
    fila.Multiply(myTrsf);
    TopLoc_Location LocLast(fila);
    if (!myLoc->IsClosed() || LocFirst != LocLast) {
        myLast = myProfile;
        if (!LocLast.IsIdentity()) {
            //myLast.Location(LocLast.Multiplied(myProfile.Location()) );
            myLast = BRepBuilderAPI_Transform(myProfile, fila, Standard_True); //copy
        }
    }
    else {
        myLast = myFirst;
    }
    RemLoc.Remove(myLast);
    myLast = RemLoc.GetResult();
    NCollection_Sequence<TopoDS_Edge> es=SplitShapebyaxis(gw, axis);
    

    Viewer vout(50, 50, 500, 500);
    vout << wbe;
    vout << xline;
    vout << yline;
    vout << zline;
    vout << gw;
    vout << axis;
    // 遍历点集合
    for (int i = 1; i <= es.Length(); ++i) {
        vout << es.Value(i);
    }
    vout.StartMessageLoop();
    return 0;
}
相关推荐
宗浩多捞29 分钟前
C++设计模式(更新中)
开发语言·c++·设计模式
Smart-Space42 分钟前
HtmlRender - c++实现的html生成类
c++·html
学习使我变快乐3 小时前
C++:析构函数
开发语言·c++
Aomnitrix3 小时前
网络协议全景:Linux环境下的TCP/IP、UDP
linux·运维·网络·c++·网络协议·tcp/ip·运维开发
我言秋日胜春朝★3 小时前
【C++】继承详解
开发语言·c++
DA树聚6 小时前
大语言模型之ICL(上下文学习) - In-Context Learning Creates Task Vectors
人工智能·学习·程序人生·ai·语言模型·自然语言处理·easyui
禁默7 小时前
list从0到1的突破
数据结构·c++·list
laocooon5238578867 小时前
一个线性筛的多功能组合:筛法求质数+约数个数+约数和
数据结构·c++·算法
神一样的老师8 小时前
使用卷积神经网络进行人类活动识别的特征学习:惯性测量单元和音频数据的案例研究
学习·cnn·音视频