在AutoCAD中使用拉伸方法创建三维实体的时候,很多人会碰到这样一个问题,分明是多个首位相连的直线段,为什么拉升的时候会导致创建实体失败呢?如何解决呢?第一种方法是将该封闭图形换做多段线(Polyline)来绘制,第二种则是使用面域(Region),将多个直线段转化为一个面域,问题也能得到了解决,下面就简单说说面域的问题。 面域,顾名思义,面就是平面,域就是范围,即平面区域。封闭区域和面域在AutoCAD中是两个不同的概念,虽然在几何上,一个封闭的平面图形确实可以表示出其所在的平面,但是在AutoCAD中,没有创建面域之前,封闭的几何体是没有面域概念的。从视觉上我们会觉得这是一个封闭的平面区域,但是AutoCAD内部并不是这样表示的,只有当利用该几何图形创建面域之后,封闭的图形才局限出一个面,该几何图形所包围的部分即为面域 在AutoCAD中,可以将封闭区域转换为面域,这些封闭区域可以是圆、椭圆、封闭的二维多段线和封闭的样条曲线等对象,也可以是由圆弧、直线、二维多段线、椭圆弧、样条曲线等多种对象构成的封闭区域。但是,在显式转换为面域之前, 面域通常有三个作用,第一个作用是用来检验图形是否是封闭的,只有能转化为面域才能说明图形是封闭的,第二个作用是计算某些几何参数,因为面域具有物理属性,如形心,面积等。第三个作用则是用来创建三维模型,因为一般的平面图形只有转化为面域才能拉伸为立体图形,这也是本文讨论的重点。 计算面积,周长
对于规则的平面图形,我们可以使用一般的计算公式求解,但是一旦图形变得稍微复杂一点,例如图形中有椭圆弧,对于周长的求解将会是一个灾难,如果还有样条曲线,传统的计算方法就显得捉襟见肘了,这个时候使用面域将是一个明智的选择。 例如下图:
使用命令”region”将该封闭区域转换为面域后,使用”massprop”命令显示该对象的属性,结果如下:
详细的几何参数都被显示出来。 实体的创建
实体的创建在AutoCAD用户交互环境下还是比较简单的,这里就不赘述了,主要讨论一下如何用程序创建三维实体。
首先,对于规则的三维实体,Solid3d类有许多现成的方法,例如CreateBox、CreateSphere等,或者是他们的布尔运算,但是许多实体并没有那么简单,这个时候面域的作用就凸显出来了,通过给Solid3d的Extrude方法传递一个面域作为参数,将能创建很大一部分的三维实体,这类实体的特点是界面轮廓比较复杂,但是每个截面是相同或者相似的。问题的重点落在如何创建一个符合要求的面域。
下面以热轧等边角钢(GB9787-88)表中的8号角钢为例详细说明复杂面域的创建。8号角钢有5种,这里只取厚度为10mm的做一个演示,截面图如下:
首先用多义线绘制该封闭区域,例如我们以下图中的顺序创建多义线:
点坐标列表: 许多人被多义线给误导了,总以为它只能创建线段,其实多义线是可以创建圆弧的,这主要有第三个参数决定,我的博客中也做了详细的说明。 然后是将该多义线转化为面域。这里要详细说明一下。根据《AutoCAD.NET Developer’s Guide》一书中的说明,这个时候要使用Region的静态方法CreateFromCurves,这个方法很有意思,它的输入参数是一个对象集合(DBObjectCollection),该集合包含了创建面域的封闭区域,输出参数也是一个对象集合,该对象则是包含了创建好的面域的集合。或许有些人会感到疑惑:为什么不直接返回一个面域呢?书中也做了详细的解释:如果两个或以上的曲线共享一个终点的话,创建的结果将会是随意的,基于这一原因,CreateFromCurves实际上会创建多个面域,这也使得对象集合显得有必要了。
最后就是拉伸了。一旦面域创建好,拉升将会显得非常简单,通过使用Solid3d的Extrude方法,为该方法提供三个参数:面域,高度和斜度。
下面是代码清单:
- [CommandMethod("LBAR")]
- public void LBar()
- {
- Document doc =Application.DocumentManager.MdiActiveDocument;
- Database db = doc.Database;
- Editor ed = doc.Editor;
- Transaction trans = db.TransactionManager.StartTransaction();
- BlockTable bt = trans.GetObject(db.BlockTableId,OpenMode.ForRead) as BlockTable;
- BlockTableRecord btr = trans.GetObject(bt[BlockTableRecord.ModelSpace],OpenMode.ForWrite) as BlockTableRecord;
- Polyline p = new Polyline();
- double pi = Math.PI;
- p.AddVertexAt(0, new Point2d(0, 0), 0, 0, 0);
- p.AddVertexAt(1, new Point2d(80, 0), Math.Tan(pi / 8), 0, 0);
- p.AddVertexAt(2, new Point2d(70, 10), 0, 0, 0);
- p.AddVertexAt(3, new Point2d(19, 10), -Math.Tan(pi / 8), 0, 0);
- p.AddVertexAt(4, new Point2d(10, 19), 0, 0, 0);
- p.AddVertexAt(5, new Point2d(10, 70), Math.Tan(pi / 8), 0, 0);
- p.AddVertexAt(6, new Point2d(0, 80), 0, 0, 0);
- p.Closed = true;
- //将p添加到一个对象集合中
- DBObjectCollection dboc = new DBObjectCollection();
- dboc.Add(p);
- DBObjectCollection RegionCollection =Region.CreateFromCurves(dboc);
- //获取面域
- Region reg = RegionCollection[0] as Region;
- Solid3d sol = new Solid3d();
- sol.Extrude(reg, 200, 0);//根据面域拉升创建实体
- //添加到数据库
- btr.AppendEntity(sol);
- trans.AddNewlyCreatedDBObject(sol, true);
- trans.Commit();
- trans.Dispose();
复制代码加载,并输入“LBAR”命令后,将创建一个角钢,截图如下: |