在讲解Geom2d的点、曲线、向量之前需要先了解Geom2d_Geometry类。
Geom2d_Geometry
是 OpenCascade 中定义的一个抽象基类,用于描述二维空间中所有几何实体的共同行为。它是所有二维几何对象(如曲线、点、方向等)类的基类。它定义了几何对象的常见变换方法,例如平移、旋转、缩放和镜像等。
主要成员函数和作用:
-
几何变换:
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
。
这些方法会直接改变当前对象本身,并返回操作后的几何对象。它们是几何变换中常见的操作。
-
返回变换后的几何对象:
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
向量后的几何体。
-
变换的基础:
Transform(const gp_Trsf2d &T)
:虚函数,用于应用一个通用的二维几何变换(包括平移、旋转、缩放等)。每个具体的几何体类都会实现这个方法来进行适合其类型的变换。Transformed(const gp_Trsf2d &T) const
:返回一个经过T
变换后的新几何体。
-
复制:
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();
}
};