【OCCT+ImGUI系列】008-Geom2d-Geom2d_Geometry

在这里插入图片描述

在讲解Geom2d的点、曲线、向量之前需要先了解Geom2d_Geometry类
在这里插入图片描述
Geom2d_Geometry 是 OpenCascade 中定义的一个抽象基类,用于描述二维空间中所有几何实体的共同行为。它是所有二维几何对象(如曲线、点、方向等)类的基类。它定义了几何对象的常见变换方法,例如平移、旋转、缩放和镜像等。

主要成员函数和作用:

  1. 几何变换:

    • Mirror(const gp_Pnt2d &P):以点 P 为对称中心,执行镜像变换。
    • Mirror(const gp_Ax2d &A):以 A 为对称轴,执行镜像变换。
    • Rotate(const gp_Pnt2d &P, const Standard_Real Ang):围绕点 P 旋转几何体,Ang 是旋转角度(弧度)。
    • Scale(const gp_Pnt2d &P, const Standard_Real S):围绕点 P 对几何体进行缩放,S 为缩放因子。
    • Translate(const gp_Vec2d &V):对几何体执行平移,V 是平移的向量。
    • Translate(const gp_Pnt2d &P1, const gp_Pnt2d &P2):将几何体从点 P1 平移到点 P2

    这些方法会直接改变当前对象本身,并返回操作后的几何对象。它们是几何变换中常见的操作。

  2. 返回变换后的几何对象:

    • Mirrored(const gp_Pnt2d &P) const:返回一个以 P 为对称中心的镜像几何体。
    • Rotated(const gp_Pnt2d &P, const Standard_Real Ang) const:返回一个围绕 P 旋转 Ang 角度后的几何体。
    • Scaled(const gp_Pnt2d &P, const Standard_Real S) const:返回一个围绕 P 缩放 S 倍后的几何体。
    • Translated(const gp_Vec2d &V) const:返回一个平移 V 向量后的几何体。
  3. 变换的基础:

    • Transform(const gp_Trsf2d &T):虚函数,用于应用一个通用的二维几何变换(包括平移、旋转、缩放等)。每个具体的几何体类都会实现这个方法来进行适合其类型的变换。
    • Transformed(const gp_Trsf2d &T) const:返回一个经过 T 变换后的新几何体。
  4. 复制:

    • Copy():纯虚函数,用于返回几何体的一个副本。每个派生类都会实现该函数。

变换类型:

  • 平移(Translation):将几何体移动到新的位置,通常使用向量来表示。
  • 旋转(Rotation):围绕某个点进行旋转,旋转角度通常是以弧度为单位。
  • 镜像(Mirror):通过对称轴或对称点来进行反转操作。
  • 缩放(Scale):将几何体按比例进行放大或缩小,通常围绕某个点进行。

我们以Geom2d_Line为例,看看镜像旋转的效果。

首先生成Geom2d_Line
// 在XY平面创建初始线段
gp_Pnt2d p1(0.0, 0.0);          // 起点坐标
gp_Dir2d dir(1.0, 1.0);         // 方向向量
originalLine = new Geom2d_Line(p1, dir);

// 转换为可视化对象
Handle(AIS_Shape) CreateLineShape(...) {
    gp_Pnt origin3D(p2d.X(), p2d.Y(), 0); // 投影到Z=0平面
    gp_Dir dir3D(d2d.X(), d2d.Y(), 0);
    Handle(Geom_Curve) curve3d = new Geom_Line(origin3D, dir3D);
    TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(curve3d, -50, 50);
    // 创建AIS可视化对象...
}

关键点

  • Geom2d_Line表示纯数学二维线
  • 通过投影到Z=0平面实现三维可视化
  • BRepBuilderAPI_MakeEdge生成拓扑边
选择镜像点

在这里插入图片描述

    // 更新镜像点位置
    void UpdateMirrorPoint(const Handle(AIS_InteractiveContext)& context) {
        gp_Pnt mirrorPnt(mirrorPt[0], mirrorPt[1], 0);
        BRepBuilderAPI_MakeVertex vertex(mirrorPnt);
        mirrorPointAIS->SetShape(vertex);
        context->Redisplay(mirrorPointAIS, Standard_False);
    }
进行镜像操作
void ApplyMirror(MirrorType type) {
    Handle(Geom2d_Geometry) geo = originalLine->Copy();
    
    if(type == MirrorType::Point) {
        gp_Pnt2d mirrorPoint(mirrorPt[0], mirrorPt[1]);
        geo->Mirror(mirrorPoint);  // 点对称变换
    } 
    else { // 关于轴镜像
        gp_Ax2d axis(gp_Pnt2d(...), gp_Dir2d(1,0));
        geo->Mirror(axis);        // 轴对称变换
    }
}

点镜像
在这里插入图片描述

轴镜像
在这里插入图片描述

旋转操作

在这里插入图片描述

void ApplyRotation() {
    gp_Pnt2d center(rotateCenter[0], rotateCenter[1]);
    Standard_Real radians = rotateAngle * M_PI / 180.0;
    
    originalLine->Rotate(center, radians); // 绕指定中心旋转
}

应用:

这个类和它的派生类提供了对几何对象进行各种变换的功能。在实际应用中,可以使用这些方法来变换各种几何实体(如曲线、线段、圆等),而且这些变换方法是不可逆的,可以直接修改原始对象或返回新的对象。

代码

#pragma once

#include "pch.h"
#include <Geom2d_Line.hxx>
#include <Geom2d_Geometry.hxx>
#include <AIS_Shape.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <TopoDS_Edge.hxx>
#include "BaseScene.h"
#include "VisSceneComponents.h"
#include "TutorialWindow.h"
#include <Geom_Curve.hxx>
#include <Geom_Line.hxx>
#include <Geom2d_Transformation.hxx>

class Geom2d008 : public BaseScene, public VisSceneComponents, public TutorialWindow {
public:
    Geom2d008() { openTutorialWindow(); }

    void displayScene(const Handle(V3d_View)& view, const Handle(AIS_InteractiveContext)& context) override {
        if (!bIsSceneInit) {
            sceneInit(view, context);
            bIsSceneInit = true;
        }
        renderTutorialWindow(context);
    }

    void customInitTutorialWindow(const Handle(AIS_InteractiveContext)& context) override {}

    void sceneInit(const Handle(V3d_View)&, const Handle(AIS_InteractiveContext)& context) override {
        // 原始二维线
        gp_Pnt2d p1(0.0, 0.0);
        gp_Dir2d dir(1.0, 1.0);
        originalLine = new Geom2d_Line(p1, dir);

        // 显示原始线(蓝色)
        originalAIS = CreateLineShape(originalLine, Quantity_NOC_BLUE);
        context->Display(originalAIS, Standard_False);

        // 显示初始镜像点
        VisualizeMirrorPoint(context);
    }

    void renderTutorialContent(const Handle(AIS_InteractiveContext)& context) override {
        ImGui::Text("Transformation Parameters");

        ImGui::SliderFloat2("Mirror Point", mirrorPt, -50.0f, 50.0f);
        ImGui::SliderFloat("Rotate Angle", &rotateAngle, 0.0f, 360.0f);

        UpdateMirrorPoint(context);

        ImGui::Text("Transformations:");
        if (ImGui::Button("Mirror about Point")) ApplyMirror(context, MirrorType::Point);
        if (ImGui::Button("Mirror about Axis")) ApplyMirror(context, MirrorType::Axis);
        if (ImGui::Button("Rotate Line")) ApplyRotation(context);
        if (ImGui::Button("Reset")) ResetLine(context);
    }

private:
    enum class MirrorType { Point, Axis };

    Handle(Geom2d_Line) originalLine;
    Handle(Geom2d_Line) transformedLine;
    Handle(AIS_Shape) originalAIS;
    Handle(AIS_Shape) transformedAIS;
    Handle(AIS_Shape) mirrorPointAIS;

    float mirrorPt[2] = { 10.0f, 10.0f };
    float rotateCenter[2] = { 0.0f, 0.0f };
    float rotateAngle = 45.0f;
    float scaleFactor = 1.5f;

    // 创建线段AIS对象(从2D线转为3D可视化)
    Handle(AIS_Shape) CreateLineShape(const Handle(Geom2d_Line)& line, Quantity_NameOfColor color) {
        gp_Pnt2d p2d = line->Location();
        gp_Dir2d d2d = line->Direction();
        gp_Pnt origin3D(p2d.X(), p2d.Y(), 0);
        gp_Dir dir3D(d2d.X(), d2d.Y(), 0);
        Handle(Geom_Curve) curve3d = new Geom_Line(origin3D, dir3D);

        TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(curve3d, -50, 50);
        Handle(AIS_Shape) ais = new AIS_Shape(edge);
        ais->SetColor(color);
        return ais;
    }

    // 显示镜像点
    void VisualizeMirrorPoint(const Handle(AIS_InteractiveContext)& context) {
        gp_Pnt mirrorPnt(mirrorPt[0], mirrorPt[1], 0);
        mirrorPointAIS = new AIS_Shape(BRepBuilderAPI_MakeVertex(mirrorPnt));
        mirrorPointAIS->SetColor(Quantity_NOC_RED);
        context->Display(mirrorPointAIS, Standard_False);
    }

    // 更新镜像点位置
    void UpdateMirrorPoint(const Handle(AIS_InteractiveContext)& context) {
        gp_Pnt mirrorPnt(mirrorPt[0], mirrorPt[1], 0);
        BRepBuilderAPI_MakeVertex vertex(mirrorPnt);
        mirrorPointAIS->SetShape(vertex);
        context->Redisplay(mirrorPointAIS, Standard_False);
    }

    // 镜像变换
    void ApplyMirror(const Handle(AIS_InteractiveContext)& context, MirrorType type) {
        Handle(Geom2d_Geometry) geo = originalLine->Copy();
        if (type == MirrorType::Point) {
            geo->Mirror(gp_Pnt2d(mirrorPt[0], mirrorPt[1]));
        }
        else {
            gp_Ax2d axis(gp_Pnt2d(mirrorPt[0], mirrorPt[1]), gp_Dir2d(1.0, 0.0));
            geo->Mirror(axis);
        }
        transformedLine = Handle(Geom2d_Line)::DownCast(geo);
        ShowTransformedLine(context, Quantity_NOC_RED);
    }

    // 旋转变换
    void ApplyRotation(const Handle(AIS_InteractiveContext)& context) {
        Handle(Geom2d_Geometry) geo = originalLine->Copy();
        geo->Rotate(gp_Pnt2d(rotateCenter[0], rotateCenter[1]), rotateAngle * M_PI / 180.0);
        transformedLine = Handle(Geom2d_Line)::DownCast(geo);
        ShowTransformedLine(context, Quantity_NOC_GREEN);
    }

    // 显示变换后线段(覆盖旧变换)
    void ShowTransformedLine(const Handle(AIS_InteractiveContext)& context, Quantity_NameOfColor color) {
        if (!transformedAIS.IsNull()) {
            context->Remove(transformedAIS, Standard_False);
        }
        transformedAIS = CreateLineShape(transformedLine, color);
        context->Display(transformedAIS, Standard_False);
        context->UpdateCurrentViewer();
    }

    // 重置,仅清除变换线
    void ResetLine(const Handle(AIS_InteractiveContext)& context) {
        if (!transformedAIS.IsNull()) {
            context->Remove(transformedAIS, Standard_False);
            transformedAIS.Nullify();
        }
        context->UpdateCurrentViewer();
    }
};

在OpenCASCADE Technology (OCCT) 的几何模块中,`Geom2d_TrimmedCurve` 是一种二维修剪曲线,它代表了由原始曲线经过修剪操作得到的结果,即删除了一些部分后的剩余部分。如果你想要将这样的修剪曲线转换成边缘(`Edge`),你需要通过一系列的几何处理步骤: 1. 首先,确认修剪曲线是否是一个封闭的轮廓,因为`Edge`通常对应于线段或面边界的边界线。 2. 如果`Geom2d_TrimmedCurve`是一个封闭的轮廓,你可以使用 `BRepBuilderAPI_MakeWire` 函数将其封装到二维布尔模型(Wire)中,然后创建一个平面表面 (`TopoDS_Shape`)。 3. 使用 `BRepBuilderAPI_Transform` 将这个二维表面从笛卡尔坐标系变换到三维空间中的某个坐标位置,以便于与三维实体关联起来。 4. 然后,利用 `BRepTools::Add` 或者 `BRepTools::MakeEdgeFromShape` 将生成的二维形状转换为 `TopoDS_Edge` 对象,这一步将最终创建出所需的边缘。 ```cpp // 示例代码 Geom2d_Curve curve = ...; // 原始曲线 Geom2d_TrimmedCurve trimmed_curve = ...; // 修剪后的曲线 // 创建包围线并转换为三维 TopoDS_Wire wire = BRepBuilderAPI_MakeWire(trimmed_curve); TopoDS_Shape shape = TopoDS.hxx.TopoDS_Shape(wire); // 可选:变换到三维空间 gp_Pnt3d translation_point(0, 0, z_coordinate); // 根据需要设置三维位置 TopoDS_Shape transformed_shape = BRepBuilderAPI_Transform(shape, translation_point); // 转换为Edge TopoDS_Edge edge; if (BRepTools::Add(transformed_shape, edge)) { // 成功创建 Edge } else { // 处理错误 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值