一、Graphics
类的本质与作用
Graphics
是 .NET 框架中 System.Drawing
命名空间下的核心类,用于在二维画布(如 Bitmap
图像)上绘制图形、文本或图像。它相当于 “绘图工具”,提供了一系列方法(如 DrawLine
、FillEllipse
、DrawString
等),可以操作画笔(Pen
)、画刷(Brush
)、字体(Font
)等对象,将几何图形、文本或图像渲染到指定的画布上。
二、能否用 Graphics
绘制模型空间中的图形?
可以,但需要分两步走:先从 CAD 模型空间中提取几何数据,再将数据转换为 Graphics
能识别的图形对象。
步骤 1:从模型空间提取几何数据
在 CAD 开发中(如 AutoCAD、基于 Teigha 库的 DWG 处理),模型空间(Model Space)存储了图纸的核心几何对象(如线段、圆、多边形、文本等)。要绘制这些图形,需先通过 CAD 库的 API 提取这些几何实体。
例如,使用 Database
对象访问模型空间的块定义(BlockDefinition
),遍历其中的实体(Entity
):
// 开启数据库事务
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// 获取块表(BlockTable)
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
// 获取模型空间的块表记录(BlockTableRecord)
BlockTableRecord modelSpace = (BlockTableRecord)tr.GetObject(
bt[BlockTableRecord.ModelSpace],
OpenMode.ForRead
);
// 遍历模型空间中的所有实体
foreach (ObjectId entityId in modelSpace)
{
try
{
// 打开实体对象
Entity entity = (Entity)tr.GetObject(entityId, OpenMode.ForRead);
// 根据实体类型进行不同处理
if (entity is Line line)
{
// 处理线段 - 获取起点和终点坐标
Point3d startPoint = line.StartPoint;
Point3d endPoint = line.EndPoint;
// 其他线段处理逻辑...
}
else if (entity is Circle circle)
{
// 处理圆形 - 获取圆心和半径
Point3d center = circle.Center;
double radius = circle.Radius;
// 其他圆形处理逻辑...
}
else if (entity is Arc arc)
{
// 处理圆弧 - 获取圆心、半径、起始角度和结束角度
Point3d center = arc.Center;
double radius = arc.Radius;
double startAngle = arc.StartAngle;
double endAngle = arc.EndAngle;
// 其他圆弧处理逻辑...
}
else if (entity is Polyline polyline)
{
// 处理多段线 - 遍历顶点
for (int i = 0; i < polyline.CoordinateCount; i++)
{
Point2d vertex = polyline.GetPoint2dAt(i);
// 其他顶点处理逻辑...
}
}
else if (entity is BlockReference blockRef)
{
// 处理块引用 - 获取块名和插入点
string blockName = blockRef.Name;
Point3d insertionPoint = blockRef.Position;
// 其他块引用处理逻辑...
}
// 可以继续添加其他实体类型的处理...
}
catch (System.Exception ex)
{
// 处理实体读取异常
Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(
"\n读取实体时出错: " + ex.Message
);
}
}
// 提交事务
tr.Commit();
}
步骤 2:将几何数据转换为 Graphics
可绘制的图形
Graphics
只能识别二维平面中的坐标(基于画布的像素坐标系),而 CAD 模型空间的坐标可能非常大(如以毫米为单位的工程坐标),因此需要坐标变换(缩放、平移、旋转等),将 CAD 坐标映射到缩略图的画布坐标(如 200x200 像素)。
示例:用 Graphics
绘制模型空间中的线段
假设模型空间中有一条线段(起点 (100, 200)
,终点 (500, 800)
),需要将其缩放到 200x200 的缩略图中:
private Bitmap DrawModelSpaceToThumbnail(Database db)
{
// 1. 创建 200x200 的缩略图画布
Bitmap thumbnail = new Bitmap(200, 200);
using (Graphics g = Graphics.FromImage(thumbnail))
{
g.SmoothingMode = SmoothingMode.AntiAlias; // 抗锯齿
g.Clear(Color.White); // 背景色
// 2. 获取模型空间的实体(示例简化逻辑)
var modelSpaceEntities = GetModelSpaceEntities(db);
// 3. 计算坐标变换参数(关键!)
// 假设模型空间的最大范围是 (0,0) 到 (1000, 1000),缩略图尺寸 200x200
double scale = 200.0 / 1000.0; // 缩放比例(模型空间单位 → 像素)
float offsetX = 0; // 平移偏移(可根据需要调整)
float offsetY = 0;
// 4. 绘制每个实体
foreach (Entity entity in modelSpaceEntities)
{
switch (entity)
{
case Line line:
// 将 CAD 坐标转换为缩略图坐标
PointF start = new PointF(
(float)(line.StartPoint.X * scale) + offsetX,
(float)(line.StartPoint.Y * scale) + offsetY
);
PointF end = new PointF(
(float)(line.EndPoint.X * scale) + offsetX,
(float)(line.EndPoint.Y * scale) + offsetY
);
// 用 Graphics 绘制线段
g.DrawLine(Pens.Blue, start, end);
break;
case Circle circle:
// 转换圆心和半径
PointF center = new PointF(
(float)(circle.Center.X * scale) + offsetX,
(float)(circle.Center.Y * scale) + offsetY
);
float radius = (float)(circle.Radius * scale);
// 绘制圆形
g.DrawEllipse(Pens.Red, center.X - radius, center.Y - radius, 2 * radius, 2 * radius);
break;
// 其他实体类型(如 Polyline、Arc 等)类似处理...
}
}
}
return thumbnail;
}
// 辅助方法:获取模型空间中的实体(需根据实际 CAD 库调整)
private List<Entity> GetModelSpaceEntities(Database db)
{
List<Entity> entities = new List<Entity>();
using (BlockTable blockTable = (BlockTable)db.BlockTableId.Open(OpenMode.ForRead))
using (BlockTableRecord modelSpace = (BlockTableRecord)blockTable[BlockTableRecord.ModelSpace].Open(OpenMode.ForRead))
{
foreach (ObjectId entityId in modelSpace)
{
if (entityId.IsErased) continue;
entities.Add((Entity)entityId.Open(OpenMode.ForRead));
}
}
return entities;
}
关键注意事项
- 坐标变换:CAD 模型空间的坐标通常很大(如以米 / 毫米为单位),需要根据缩略图尺寸计算缩放比例(
scale = 缩略图宽度 / 模型空间宽度
),确保图形适配到小画布。 - 实体类型支持:需针对不同 CAD 实体(
Line
、Circle
、Polyline
、Text
等)编写对应的绘制逻辑,Graphics
提供了DrawLine
、DrawEllipse
、DrawString
等方法覆盖常见类型。 - 性能优化:若模型空间包含大量实体,建议过滤掉小尺寸或不可见的实体(如隐藏层、极细线条),避免缩略图过于复杂。
总结
Graphics
是 .NET 中用于二维绘图的核心工具,结合 CAD 库提取模型空间的几何数据后,可以通过坐标变换将模型空间的图形绘制到缩略图中。实际开发中需根据 CAD 库的具体 API(如 AutoCAD 的 ObjectARX
、Teigha 的 Rx
库)调整实体获取和坐标转换逻辑。