当前位置:   article > 正文

(7)ObjectARX2015 + vs2012创建多段线以及实体的旋转移动放缩_arx 多段线顶点的凸出值

arx 多段线顶点的凸出值

  提示:看之前的博客(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. 思路

        ObjectARX 中提供了三种多段线的相关类: AcDbPolyline AcDb2dPolyline
AcDb3dPolyline 。其中,利用 AutoCAD 的内部命令可以创建 AcDbPolyline AcDb3dPolyline
类的对象,用 PLINE 命令创建的对象是轻量多段线( AcDbPolyline ),用 3DPOLY 命令创建
的对象是三维多段线( AcDb3dPolyline )。鉴于 AcDb2dPolyline 目前并不常用,本节不准备详
细讨论它。
        创建轻量多段线和三维多段线的函数,直接封装 AcDbPolyline AcDb3dPolyline 类的构
造函数即可;创建正多边形、矩形、圆形和圆环,实际上都是创建了特殊形状的轻量多段线,
创建这些对象的关键都在于顶点和凸度的确定。
3. 步骤
(1) 在CCreateEnt类中:添加一个函数 CreatePolyline,用于向模型空间添加轻量多段线.
        创建 AcDbPolyline 对象可以分成两个步骤:创建类的实例和添加顶点。
        创建类的实例, 以多段线的顶点个数作为参数调用 AcDbPolyline::AcDbPolyline 函数;
        添加顶点时,则使用了 AcDbPolyline::addVertexAt 函数,将每一个顶点添加到多段线中。
  1. //创建轻量多段线
  2. static AcDbObjectId CreatePolyline(AcGePoint2dArray points, double width = 0);
  1. //创建轻量多段线
  2. //创建 AcDbPolyline 对象可以分成两个步骤:创建类的实例和添加顶点
  3. AcDbObjectId CCreateEnt::CreatePolyline(AcGePoint2dArray points, double width)
  4. {
  5. //创建类的实例, 以多段线的顶点个数作为参数调用 AcDbPolyline::AcDbPolyline 函数;
  6. int numVertices = points.length();
  7. AcDbPolyline *pPoly = new AcDbPolyline(numVertices);
  8. for (int i = 0; i < numVertices; i++)
  9. {
  10. //添加顶点时,则使用了 AcDbPolyline::addVertexAt 函数,将每一个顶点添加到多段线中。
  11. pPoly->addVertexAt(i, points.at(i), 0, width, width);
  12. }
  13. /*
  14. //addVertexAt 函数定义为:
  15. Acad::ErrorStatus addVertexAt(
  16. unsigned int index, //index 用来指定插入顶点的索引号(从 0 开始);
  17. const AcGePoint2d& pt, //pt 指定顶点的位置;
  18. double bulge = 0., //bulge 指出要创建的顶点的凸度;
  19. double startWidth = -1., //startWidth 和 endWidth 指定了从该顶点到下一顶点之间连线的起始和终止线宽,
  20. double endWidth = -1); //利用该特性可以使用多段线创建一个实心箭头。
  21. */
  22. AcDbObjectId polyId;
  23. polyId = CCreateEnt::PostToModelSpace(pPoly);
  24. return polyId;
  25. }

        凸度是多段线中一个比较难理解的概念,用于指定当前顶点的平滑性,其被定义为:在
        多段线顶点显示中,选取顶点与下一个顶点形成的弧之间角度的四分之一的正切值。凸度可
        以用来设置多段线某一段的凸出参数,0 表示直线,1 表示半圆,介于 0~1 之间为劣弧,大
        于 1 为优弧。在创建圆的函数中,你会进一步学习。

(2) 创建仅包含一条直线的多段线

  1. //创建仅包含一条直线的多段线
  2. static AcDbObjectId CreatePolyline(AcGePoint2d ptStart, AcGePoint2d ptEnd, double width);
  1. //创建仅包含一条直线的多段线
  2. AcDbObjectId CCreateEnt::CreatePolyline(AcGePoint2d ptStart, AcGePoint2d ptEnd, double width)
  3. {
  4. AcGePoint2dArray points;
  5. points.append(ptStart);
  6. points.append(ptEnd);
  7. return CreatePolyline(points, width);
  8. }

(3) 添加一个创建三维多段线的函数

  1. //添加一个创建三维多段线的函数
  2. static AcDbObjectId Create3dPolyline(AcGePoint3dArray points);
  1. //添加一个创建三维多段线的函数
  2. AcDbObjectId CCreateEnt::Create3dPolyline(AcGePoint3dArray points)
  3. {
  4. AcDb3dPolyline *pPoly3d = new AcDb3dPolyline(AcDb::k3dSimplePoly, points);
  5. return CCreateEnt::PostToModelSpace(pPoly3d);
  6. /*
  7. AcDb3dPolyline 类的构造函数接受了三个参数:
  8. 第一个参数值 AcDb::k3dSimplePoly 表示创建的多段线是一个未经拟合的标准多段线;
  9. 第二个参数值指定了创建三维多段线的顶点数组;
  10. 第三个参数指定是否闭合多段线,这里使用了默认参数值,不在创建多段线时将其闭合。
  11. */
  12. }

(4) 在 CModifyEnt 类中,添加一个函数 Rotate,按照指定的角度(用弧度值表示)旋转指定的实体.

AcDbEntity::transformBy 函数对实体进行旋转,该函数能对实体进行比例变换、移动和旋转操作,其输入参数是一个几何变换矩阵(AcGeMatrix3d 类)
AcGeMatrix3d 类用于实体的几何变换非常简单,只要使用 setToScaling setToRotation setToTranslation
三个函数设置所要进行的变换,然后对所要变换的实体执行 transformBy 函数即可。
move和scale同理.

  1. Acad::ErrorStatus Rotate(AcDbObjectId entId, AcGePoint2d ptBase, double rotation); //旋转实体
  2. Acad::ErrorStatus Move(AcDbObjectId entId, AcGePoint3d ptBase, AcGePoint3d ptDest); //移动实体
  3. Acad::ErrorStatus Scale(AcDbObjectId entId, AcGePoint3d ptBase, double scaleFactor); //缩放实体
  1. //旋转实体
  2. Acad::ErrorStatus CModifyEnt::Rotate(AcDbObjectId entId, AcGePoint2d ptBase, double rotation)
  3. {
  4. CGeometryOper m_geometryOper;
  5. AcGeMatrix3d xform;
  6. AcGeVector3d vec(0, 0, 1);
  7. xform.setToRotation(rotation, vec, m_geometryOper.Pt2dTo3d(ptBase));
  8. AcDbEntity *pEnt;
  9. Acad::ErrorStatus es = acdbOpenObject(pEnt, entId, AcDb::kForWrite, false);
  10. pEnt->transformBy(xform);
  11. pEnt->close();
  12. return es;
  13. }
  14. //移动实体
  15. Acad::ErrorStatus CModifyEnt::Move(AcDbObjectId entId, AcGePoint3d ptBase, AcGePoint3d ptDest)
  16. {
  17. // 设置变换矩阵的参数
  18. AcGeMatrix3d xform;
  19. AcGeVector3d vec(ptDest.x - ptBase.x, ptDest.y - ptBase.y, ptDest.z - ptBase.z);
  20. xform.setToTranslation(vec);
  21. AcDbEntity *pEnt;
  22. Acad::ErrorStatus es = acdbOpenObject(pEnt, entId, AcDb::kForWrite, false);
  23. pEnt->transformBy(xform);
  24. pEnt->close();
  25. return es;
  26. }
  27. //缩放实体
  28. Acad::ErrorStatus CModifyEnt::Scale(AcDbObjectId entId, AcGePoint3d ptBase, double scaleFactor)
  29. {
  30. // 设置变换矩阵的参数
  31. AcGeMatrix3d xform;
  32. xform.setToScaling(scaleFactor, ptBase);
  33. AcDbEntity *pEnt;
  34. Acad::ErrorStatus es = acdbOpenObject(pEnt, entId, AcDb::kForWrite, false);
  35. pEnt->transformBy(xform);
  36. pEnt->close();
  37. return es;
  38. }

(5) 添加创建正多边形的函数。创建正多边形的输入参数为中心、边数、外接圆半径、 旋转角度(弧度值)和线宽

        步骤 (a)计算顶点位置;

                (b)根据顶点位置创建多段线;

                (c)闭合多段线;

                (d)旋转多段线。

        步骤(c) 是新接触到的内容。前面已经介绍过,使用 acdbOpenAcDbEntity 函数能够得到一个指向 AcDbEntity 对象的指针,但是如何将其转化为指向 AcDbPolyline 的指针,从而利用AcDbPolylien 类的函数修改其特性呢?注意下面的语句:
                        AcDbPolyline *pPoly = AcDbPolyline::cast(pEnt);
        cast 是 ObjectARX 所有类的基类 AcRxObject 中实现的一个函数,该函数提供了一种
安全的类型转换机制,这里的作用就是从基类指针 pEnt 获得派生类的指针 pPoly

    如果你想为这条语句加上一个错误处理,还可以写成这样的形式:

  1. if (pEnt->isKindOf(AcDbPolyline::desc()) == Adesk::kTrue)
  2. {
  3. AcDbPolyline *pPoly = AcDbPolyline::cast(pEnt);
  4. if (pPoly != NULL)
  5. {
  6. pPoly->setClosed(Adesk::kTrue);
  7. }
  8. }
        isKindOf 和 desc 函数提供了 ObjectARX 中一种常用的动态类型检查机制,这种方法在
ObjectARX 编程中极为常见。

代码如下:

  1. //添加创建正多边形的函数(中心、边数、外接圆半径、旋转角度(弧度值)和线宽)
  2. static AcDbObjectId CreatePolygon(AcGePoint2d ptCenter, int number, double radius, double rotation, double width);
  1. //添加创建正多边形的函数(中心、边数、外接圆半径、旋转角度(弧度值)和线宽)
  2. //步骤(a)计算顶点位置;(b)根据顶点位置创建多段线;(c)闭合多段线;(d)旋转多段线。
  3. AcDbObjectId CCreateEnt::CreatePolygon(AcGePoint2d ptCenter, int number, double radius, double rotation, double width)
  4. {
  5. CGeometryOper m_geometryOper;
  6. AcGePoint2dArray points;
  7. double angle = 2 * m_geometryOper.PI() / (double)number;
  8. //1.计算顶点位置;
  9. for (int i = 0; i < number; i++)
  10. {
  11. AcGePoint2d pt;
  12. pt.x = ptCenter.x + radius * cos(i * angle);
  13. pt.y = ptCenter.y + radius * sin(i * angle);
  14. points.append(pt);
  15. }
  16. //2.根据顶点位置创建多段线;
  17. AcDbObjectId polyId= CCreateEnt::CreatePolyline(points, width);
  18. //3.闭合多段线;
  19. AcDbEntity *pEnt;
  20. acdbOpenAcDbEntity(pEnt, polyId, AcDb::kForWrite);
  21. AcDbPolyline *pPoly = AcDbPolyline::cast(pEnt);
  22. if (pPoly != NULL)
  23. {
  24. pPoly->setClosed(Adesk::kTrue);
  25. }
  26. pEnt->close();
  27. //4.旋转多段线。
  28. CModifyEnt m_modifyEnt;
  29. m_modifyEnt.Rotate(polyId, ptCenter, rotation);
  30. return polyId;
  31. }

(6) 多线段矩形(两个角点、线宽)

先在CGeometryOper类中添加取最大最小值得函数

  1. double Max(double a, double b);
  2. double Min(double a, double b);
  1. //求最大值
  2. double CGeometryOper::Max(double a, double b)
  3. {
  4. if (a > b)
  5. {
  6. return a;
  7. }
  8. else
  9. {
  10. return b;
  11. }
  12. }
  13. //求最小值
  14. double CGeometryOper::Min(double a, double b)
  15. {
  16. if (a < b)
  17. {
  18. return a;
  19. }
  20. else
  21. {
  22. return b;
  23. }
  24. }

再在CCreateEnt类中添加创建矩形函数

  1. //矩形(两个角点、线宽)
  2. static AcDbObjectId CreateRectangle(AcGePoint2d pt1, AcGePoint2d pt2, double width);
  1. //矩形(两个角点、线宽)
  2. AcDbObjectId CCreateEnt::CreateRectangle(AcGePoint2d pt1, AcGePoint2d pt2, double width)
  3. {
  4. // 提取两个角点的坐标值
  5. double x1 = pt1.x, x2 = pt2.x;
  6. double y1 = pt1.y, y2 = pt2.y;
  7. // 计算矩形的角点
  8. CGeometryOper m_geometryOper;
  9. AcGePoint2d ptLeftBottom(m_geometryOper.Min(x1, x2),
  10. m_geometryOper.Min(y1, y2));
  11. AcGePoint2d ptRightBottom(m_geometryOper.Max(x1, x2),
  12. m_geometryOper.Min(y1, y2));
  13. AcGePoint2d ptRightTop(m_geometryOper.Max(x1, x2),
  14. m_geometryOper.Max(y1, y2));
  15. AcGePoint2d ptLeftTop(m_geometryOper.Min(x1, x2),
  16. m_geometryOper.Max(y1, y2));
  17. // 创建对应的多段线
  18. AcDbPolyline *pPoly = new AcDbPolyline(4);
  19. pPoly->addVertexAt(0, ptLeftBottom, 0, width, width);
  20. pPoly->addVertexAt(1, ptRightBottom, 0, width, width);
  21. pPoly->addVertexAt(2, ptRightTop, 0, width, width);
  22. pPoly->addVertexAt(3, ptLeftTop, 0, width, width);
  23. pPoly->setClosed(Adesk::kTrue);
  24. // 将多段线添加到模型空间
  25. AcDbObjectId polyId;
  26. polyId = CCreateEnt::PostToModelSpace(pPoly);
  27. return polyId;
  28. }

(7) 多线段圆(圆心、半径和线宽)

  1. //多线段圆(圆心、半径和线宽)
  2. static AcDbObjectId CreatePolyCircle(AcGePoint2d ptCenter, double radius, double width);
  1. //多线段圆(圆心、半径和线宽)
  2. AcDbObjectId CCreateEnt::CreatePolyCircle(AcGePoint2d ptCenter, double radius, double width)
  3. {
  4. // 计算顶点的位置
  5. AcGePoint2d pt1, pt2, pt3;
  6. pt1.x = ptCenter.x + radius;
  7. pt1.y = ptCenter.y;
  8. pt2.x = ptCenter.x - radius;
  9. pt2.y = ptCenter.y;
  10. pt3.x = ptCenter.x + radius;
  11. pt3.y = ptCenter.y;
  12. // 创建多段线
  13. AcDbPolyline *pPoly = new AcDbPolyline(3);
  14. pPoly->addVertexAt(0, pt1, 1, width, width);
  15. pPoly->addVertexAt(1, pt2, 1, width, width);
  16. pPoly->addVertexAt(2, pt3, 1, width, width);
  17. pPoly->setClosed(Adesk::kTrue);
  18. // 将多段线添加到模型空间
  19. AcDbObjectId polyId;
  20. polyId = CCreateEnt::PostToModelSpace(pPoly);
  21. return polyId;
  22. }

(8) 多线段圆弧(圆心、半径、起始角度、终止角度和线宽)

  1. //多线段圆弧(圆心、半径、起始角度、终止角度和线宽)
  2. static AcDbObjectId CreatePolyArc(AcGePoint2d ptCenter, double radius, double angleStart, double angleEnd, double width);
  1. //多线段圆弧(圆心、半径、起始角度、终止角度和线宽)
  2. AcDbObjectId CCreateEnt::CreatePolyArc(AcGePoint2d ptCenter, double radius,
  3. double angleStart, double angleEnd, double width)
  4. {
  5. // 计算顶点的位置
  6. AcGePoint2d pt1, pt2;
  7. pt1.x = ptCenter.x + radius * cos(angleStart);
  8. pt1.y = ptCenter.y + radius * sin(angleStart);
  9. pt2.x = ptCenter.x + radius * cos(angleEnd);
  10. pt2.y = ptCenter.y + radius * sin(angleEnd);
  11. // 创建多段线
  12. AcDbPolyline *pPoly = new AcDbPolyline(3);
  13. pPoly->addVertexAt(0, pt1, tan((angleEnd - angleStart) / 4), width, width);
  14. pPoly->addVertexAt(1, pt2, 0, width, width);
  15. // 将多段线添加到模型空间
  16. AcDbObjectId polyId;
  17. polyId = CCreateEnt::PostToModelSpace(pPoly);
  18. return polyId;
  19. }

(9) 在acrxEntryPoint.cpp中添加

ACED_ARXCOMMAND_ENTRY_AUTO(CArxConfigApp, MidasMyGroup, MyDrawPolyline, MyDrawPolyline, ACRX_CMD_MODAL, NULL) //画多段线
  1. //当前项目中注册一个命令 AddPolyline
  2. static void MidasMyGroupMyDrawPolyline()
  3. {
  4. CGeometryOper m_geometryOper;
  5. // 创建三维多段线
  6. AcGePoint3d pt1(0, 0, 0), pt2(10, 0, 0), pt3(10, 10, 0), pt4(10, 10, 10);
  7. AcGePoint3dArray points;
  8. points.append(pt1);
  9. points.append(pt2);
  10. points.append(pt3);
  11. points.append(pt4);
  12. AcDbObjectId polyline3dId;
  13. polyline3dId = CCreateEnt::Create3dPolyline(points);
  14. //创建正多边形(中心、边数、外接圆半径、旋转角度(弧度值)和线宽)
  15. AcDbObjectId polygonId;
  16. polygonId = CCreateEnt::CreatePolygon(AcGePoint2d::kOrigin, 6, 15, 0, 1);
  17. // 创建圆
  18. AcGePoint2d pt5(20, 20);
  19. AcDbObjectId polyCircleId;
  20. polyCircleId = CCreateEnt::CreatePolyCircle(pt5, 10, 1);
  21. // 创建圆弧
  22. AcGePoint2d pt6(10, 15);
  23. AcDbObjectId polyArcId;
  24. polyArcId = CCreateEnt::CreatePolyArc(pt6, 15, m_geometryOper.GtoR(45), m_geometryOper.GtoR(225), 1);
  25. CModifyEnt m_modifyEnt;
  26. m_modifyEnt.ChangeColor(polyline3dId, 1);
  27. m_modifyEnt.ChangeColor(polygonId, 1);
  28. m_modifyEnt.ChangeColor(polyCircleId, 1);
  29. m_modifyEnt.ChangeColor(polyArcId, 1);
  30. }

 效果展示:

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/114357
推荐阅读
相关标签
  

闽ICP备14008679号