赞
踩
提示:看之前的博客(1)和(4),那里已经分析了创建一个图形对象的基本过程,在之前的基础上本节开始就要将着眼点放在创建实体的参数上。
(1)ObjectARX2015 + vs2012创建直线_qq_42981953的博客-CSDN博客
(4)ObjectARX2015 + vs2012扩展绘制直线的功能为绘制实体_qq_42981953的博客-CSDN博客
1. 说明
本节介绍若干个函数,分别用于创建轻量多段线、三维多段线、正多边形、矩形、圆(圆环)和圆弧。这里所说的圆形和博客(6)中创建的圆不一样,因为本节创建的圆实际上是一条闭合的多段线,可以设置线宽。
(1) 创建轻量多段线(二维点, 连接点线宽)
(2) 创建仅包含一条直线的多段线(二维起点, 二维结束点, 连接点线宽)
(3) 创建三维多段线(三维点集)
(4) ---实体操作:旋转/移动/放缩
(5) 创建正多边形(中心、边数、外接圆半径、旋转角度(弧度值)和线宽)
(6) 多线段矩形(两个角点、线宽)
(7) 多线段圆(圆心、半径和线宽)
(8) 多线段圆弧(圆心、半径、起始角度、终止角度和线宽)
2. 思路
- //创建轻量多段线
- static AcDbObjectId CreatePolyline(AcGePoint2dArray points, double width = 0);
- //创建轻量多段线
- //创建 AcDbPolyline 对象可以分成两个步骤:创建类的实例和添加顶点
- AcDbObjectId CCreateEnt::CreatePolyline(AcGePoint2dArray points, double width)
- {
- //创建类的实例, 以多段线的顶点个数作为参数调用 AcDbPolyline::AcDbPolyline 函数;
- int numVertices = points.length();
- AcDbPolyline *pPoly = new AcDbPolyline(numVertices);
-
- for (int i = 0; i < numVertices; i++)
- {
- //添加顶点时,则使用了 AcDbPolyline::addVertexAt 函数,将每一个顶点添加到多段线中。
- pPoly->addVertexAt(i, points.at(i), 0, width, width);
- }
- /*
- //addVertexAt 函数定义为:
- Acad::ErrorStatus addVertexAt(
- unsigned int index, //index 用来指定插入顶点的索引号(从 0 开始);
- const AcGePoint2d& pt, //pt 指定顶点的位置;
- double bulge = 0., //bulge 指出要创建的顶点的凸度;
- double startWidth = -1., //startWidth 和 endWidth 指定了从该顶点到下一顶点之间连线的起始和终止线宽,
- double endWidth = -1); //利用该特性可以使用多段线创建一个实心箭头。
- */
-
- AcDbObjectId polyId;
- polyId = CCreateEnt::PostToModelSpace(pPoly);
-
- return polyId;
- }
凸度是多段线中一个比较难理解的概念,用于指定当前顶点的平滑性,其被定义为:在
多段线顶点显示中,选取顶点与下一个顶点形成的弧之间角度的四分之一的正切值。凸度可
以用来设置多段线某一段的凸出参数,0 表示直线,1 表示半圆,介于 0~1 之间为劣弧,大
于 1 为优弧。在创建圆的函数中,你会进一步学习。
(2) 创建仅包含一条直线的多段线
- //创建仅包含一条直线的多段线
- static AcDbObjectId CreatePolyline(AcGePoint2d ptStart, AcGePoint2d ptEnd, double width);
- //创建仅包含一条直线的多段线
- AcDbObjectId CCreateEnt::CreatePolyline(AcGePoint2d ptStart, AcGePoint2d ptEnd, double width)
- {
- AcGePoint2dArray points;
- points.append(ptStart);
- points.append(ptEnd);
- return CreatePolyline(points, width);
- }
(3) 添加一个创建三维多段线的函数
- //添加一个创建三维多段线的函数
- static AcDbObjectId Create3dPolyline(AcGePoint3dArray points);
- //添加一个创建三维多段线的函数
- AcDbObjectId CCreateEnt::Create3dPolyline(AcGePoint3dArray points)
- {
- AcDb3dPolyline *pPoly3d = new AcDb3dPolyline(AcDb::k3dSimplePoly, points);
- return CCreateEnt::PostToModelSpace(pPoly3d);
-
- /*
- AcDb3dPolyline 类的构造函数接受了三个参数:
- 第一个参数值 AcDb::k3dSimplePoly 表示创建的多段线是一个未经拟合的标准多段线;
- 第二个参数值指定了创建三维多段线的顶点数组;
- 第三个参数指定是否闭合多段线,这里使用了默认参数值,不在创建多段线时将其闭合。
- */
- }
(4) 在 CModifyEnt 类中,添加一个函数 Rotate,按照指定的角度(用弧度值表示)旋转指定的实体.
- Acad::ErrorStatus Rotate(AcDbObjectId entId, AcGePoint2d ptBase, double rotation); //旋转实体
- Acad::ErrorStatus Move(AcDbObjectId entId, AcGePoint3d ptBase, AcGePoint3d ptDest); //移动实体
- Acad::ErrorStatus Scale(AcDbObjectId entId, AcGePoint3d ptBase, double scaleFactor); //缩放实体
- //旋转实体
- Acad::ErrorStatus CModifyEnt::Rotate(AcDbObjectId entId, AcGePoint2d ptBase, double rotation)
- {
- CGeometryOper m_geometryOper;
- AcGeMatrix3d xform;
- AcGeVector3d vec(0, 0, 1);
- xform.setToRotation(rotation, vec, m_geometryOper.Pt2dTo3d(ptBase));
-
- AcDbEntity *pEnt;
- Acad::ErrorStatus es = acdbOpenObject(pEnt, entId, AcDb::kForWrite, false);
- pEnt->transformBy(xform);
- pEnt->close();
-
- return es;
- }
-
-
- //移动实体
- Acad::ErrorStatus CModifyEnt::Move(AcDbObjectId entId, AcGePoint3d ptBase, AcGePoint3d ptDest)
- {
- // 设置变换矩阵的参数
- AcGeMatrix3d xform;
- AcGeVector3d vec(ptDest.x - ptBase.x, ptDest.y - ptBase.y, ptDest.z - ptBase.z);
- xform.setToTranslation(vec);
-
- AcDbEntity *pEnt;
- Acad::ErrorStatus es = acdbOpenObject(pEnt, entId, AcDb::kForWrite, false);
- pEnt->transformBy(xform);
- pEnt->close();
-
- return es;
- }
-
-
- //缩放实体
- Acad::ErrorStatus CModifyEnt::Scale(AcDbObjectId entId, AcGePoint3d ptBase, double scaleFactor)
- {
- // 设置变换矩阵的参数
- AcGeMatrix3d xform;
- xform.setToScaling(scaleFactor, ptBase);
-
- AcDbEntity *pEnt;
- Acad::ErrorStatus es = acdbOpenObject(pEnt, entId, AcDb::kForWrite, false);
- pEnt->transformBy(xform);
- pEnt->close();
-
- return es;
- }
(5) 添加创建正多边形的函数。创建正多边形的输入参数为中心、边数、外接圆半径、 旋转角度(弧度值)和线宽
步骤 (a)计算顶点位置;
(b)根据顶点位置创建多段线;
(c)闭合多段线;
(d)旋转多段线。
如果你想为这条语句加上一个错误处理,还可以写成这样的形式:
- if (pEnt->isKindOf(AcDbPolyline::desc()) == Adesk::kTrue)
- {
- AcDbPolyline *pPoly = AcDbPolyline::cast(pEnt);
- if (pPoly != NULL)
- {
- pPoly->setClosed(Adesk::kTrue);
- }
- }
代码如下:
- //添加创建正多边形的函数(中心、边数、外接圆半径、旋转角度(弧度值)和线宽)
- static AcDbObjectId CreatePolygon(AcGePoint2d ptCenter, int number, double radius, double rotation, double width);
- //添加创建正多边形的函数(中心、边数、外接圆半径、旋转角度(弧度值)和线宽)
- //步骤(a)计算顶点位置;(b)根据顶点位置创建多段线;(c)闭合多段线;(d)旋转多段线。
- AcDbObjectId CCreateEnt::CreatePolygon(AcGePoint2d ptCenter, int number, double radius, double rotation, double width)
- {
- CGeometryOper m_geometryOper;
- AcGePoint2dArray points;
- double angle = 2 * m_geometryOper.PI() / (double)number;
-
- //1.计算顶点位置;
- for (int i = 0; i < number; i++)
- {
- AcGePoint2d pt;
- pt.x = ptCenter.x + radius * cos(i * angle);
- pt.y = ptCenter.y + radius * sin(i * angle);
- points.append(pt);
- }
-
- //2.根据顶点位置创建多段线;
- AcDbObjectId polyId= CCreateEnt::CreatePolyline(points, width);
-
- //3.闭合多段线;
- AcDbEntity *pEnt;
- acdbOpenAcDbEntity(pEnt, polyId, AcDb::kForWrite);
- AcDbPolyline *pPoly = AcDbPolyline::cast(pEnt);
- if (pPoly != NULL)
- {
- pPoly->setClosed(Adesk::kTrue);
- }
- pEnt->close();
-
- //4.旋转多段线。
- CModifyEnt m_modifyEnt;
- m_modifyEnt.Rotate(polyId, ptCenter, rotation);
-
- return polyId;
- }
(6) 多线段矩形(两个角点、线宽)
先在CGeometryOper类中添加取最大最小值得函数
- double Max(double a, double b);
- double Min(double a, double b);
- //求最大值
- double CGeometryOper::Max(double a, double b)
- {
- if (a > b)
- {
- return a;
- }
- else
- {
- return b;
- }
- }
-
-
- //求最小值
- double CGeometryOper::Min(double a, double b)
- {
- if (a < b)
- {
- return a;
- }
- else
- {
- return b;
- }
- }
再在CCreateEnt类中添加创建矩形函数
- //矩形(两个角点、线宽)
- static AcDbObjectId CreateRectangle(AcGePoint2d pt1, AcGePoint2d pt2, double width);
- //矩形(两个角点、线宽)
- AcDbObjectId CCreateEnt::CreateRectangle(AcGePoint2d pt1, AcGePoint2d pt2, double width)
- {
- // 提取两个角点的坐标值
- double x1 = pt1.x, x2 = pt2.x;
- double y1 = pt1.y, y2 = pt2.y;
- // 计算矩形的角点
- CGeometryOper m_geometryOper;
- AcGePoint2d ptLeftBottom(m_geometryOper.Min(x1, x2),
- m_geometryOper.Min(y1, y2));
- AcGePoint2d ptRightBottom(m_geometryOper.Max(x1, x2),
- m_geometryOper.Min(y1, y2));
- AcGePoint2d ptRightTop(m_geometryOper.Max(x1, x2),
- m_geometryOper.Max(y1, y2));
- AcGePoint2d ptLeftTop(m_geometryOper.Min(x1, x2),
- m_geometryOper.Max(y1, y2));
- // 创建对应的多段线
- AcDbPolyline *pPoly = new AcDbPolyline(4);
- pPoly->addVertexAt(0, ptLeftBottom, 0, width, width);
- pPoly->addVertexAt(1, ptRightBottom, 0, width, width);
- pPoly->addVertexAt(2, ptRightTop, 0, width, width);
- pPoly->addVertexAt(3, ptLeftTop, 0, width, width);
- pPoly->setClosed(Adesk::kTrue);
- // 将多段线添加到模型空间
- AcDbObjectId polyId;
- polyId = CCreateEnt::PostToModelSpace(pPoly);
-
- return polyId;
- }
(7) 多线段圆(圆心、半径和线宽)
- //多线段圆(圆心、半径和线宽)
- static AcDbObjectId CreatePolyCircle(AcGePoint2d ptCenter, double radius, double width);
- //多线段圆(圆心、半径和线宽)
- AcDbObjectId CCreateEnt::CreatePolyCircle(AcGePoint2d ptCenter, double radius, double width)
- {
- // 计算顶点的位置
- AcGePoint2d pt1, pt2, pt3;
- pt1.x = ptCenter.x + radius;
- pt1.y = ptCenter.y;
- pt2.x = ptCenter.x - radius;
- pt2.y = ptCenter.y;
- pt3.x = ptCenter.x + radius;
- pt3.y = ptCenter.y;
- // 创建多段线
- AcDbPolyline *pPoly = new AcDbPolyline(3);
- pPoly->addVertexAt(0, pt1, 1, width, width);
- pPoly->addVertexAt(1, pt2, 1, width, width);
- pPoly->addVertexAt(2, pt3, 1, width, width);
- pPoly->setClosed(Adesk::kTrue);
- // 将多段线添加到模型空间
- AcDbObjectId polyId;
- polyId = CCreateEnt::PostToModelSpace(pPoly);
-
- return polyId;
- }
(8) 多线段圆弧(圆心、半径、起始角度、终止角度和线宽)
- //多线段圆弧(圆心、半径、起始角度、终止角度和线宽)
- static AcDbObjectId CreatePolyArc(AcGePoint2d ptCenter, double radius, double angleStart, double angleEnd, double width);
- //多线段圆弧(圆心、半径、起始角度、终止角度和线宽)
- AcDbObjectId CCreateEnt::CreatePolyArc(AcGePoint2d ptCenter, double radius,
- double angleStart, double angleEnd, double width)
- {
- // 计算顶点的位置
- AcGePoint2d pt1, pt2;
- pt1.x = ptCenter.x + radius * cos(angleStart);
- pt1.y = ptCenter.y + radius * sin(angleStart);
- pt2.x = ptCenter.x + radius * cos(angleEnd);
- pt2.y = ptCenter.y + radius * sin(angleEnd);
-
- // 创建多段线
- AcDbPolyline *pPoly = new AcDbPolyline(3);
- pPoly->addVertexAt(0, pt1, tan((angleEnd - angleStart) / 4), width, width);
- pPoly->addVertexAt(1, pt2, 0, width, width);
-
- // 将多段线添加到模型空间
- AcDbObjectId polyId;
- polyId = CCreateEnt::PostToModelSpace(pPoly);
-
- return polyId;
- }
(9) 在acrxEntryPoint.cpp中添加
ACED_ARXCOMMAND_ENTRY_AUTO(CArxConfigApp, MidasMyGroup, MyDrawPolyline, MyDrawPolyline, ACRX_CMD_MODAL, NULL) //画多段线
- //当前项目中注册一个命令 AddPolyline
- static void MidasMyGroupMyDrawPolyline()
- {
- CGeometryOper m_geometryOper;
- // 创建三维多段线
- AcGePoint3d pt1(0, 0, 0), pt2(10, 0, 0), pt3(10, 10, 0), pt4(10, 10, 10);
- AcGePoint3dArray points;
- points.append(pt1);
- points.append(pt2);
- points.append(pt3);
- points.append(pt4);
- AcDbObjectId polyline3dId;
- polyline3dId = CCreateEnt::Create3dPolyline(points);
- //创建正多边形(中心、边数、外接圆半径、旋转角度(弧度值)和线宽)
- AcDbObjectId polygonId;
- polygonId = CCreateEnt::CreatePolygon(AcGePoint2d::kOrigin, 6, 15, 0, 1);
- // 创建圆
- AcGePoint2d pt5(20, 20);
- AcDbObjectId polyCircleId;
- polyCircleId = CCreateEnt::CreatePolyCircle(pt5, 10, 1);
- // 创建圆弧
- AcGePoint2d pt6(10, 15);
- AcDbObjectId polyArcId;
- polyArcId = CCreateEnt::CreatePolyArc(pt6, 15, m_geometryOper.GtoR(45), m_geometryOper.GtoR(225), 1);
-
- CModifyEnt m_modifyEnt;
- m_modifyEnt.ChangeColor(polyline3dId, 1);
- m_modifyEnt.ChangeColor(polygonId, 1);
- m_modifyEnt.ChangeColor(polyCircleId, 1);
- m_modifyEnt.ChangeColor(polyArcId, 1);
- }
效果展示:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。