乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 107|回复: 4

多边形叠加分析(交并差)

[复制链接]

18

主题

113

帖子

10

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
184
发表于 2021-12-13 09:23:00 | 显示全部楼层 |阅读模式
MFC 的多边形叠加分析(交并差)见原帖网址:
arx的多边形叠加分析(交并差)效果图:

qkq0givfs2o.gif

qkq0givfs2o.gif


http://bbs.mjtd.com/forum.php?mod=attachment&aid=MTE3MTYxfDA5YmM3YmY5YTFmMzhkZGQ3YzNmMzZlMWY3Mjg2MDExfDE2NTkwODg3ODU%3D&request=yes&_f=.gif
arx 的不支持有弧段的多边形。
数学法计算交集与面域法计算交集的时间比较:
数学法用时: 0 毫秒
面域法用时: 2937毫秒
获取多段线顶点坐标,并加入点集合中
复制代码多边形叠加分析(交集) 测试
复制代码多边形叠加分析(并集) 测试
复制代码多边形叠加分析(差集) 测试
  1. // 创建多段线过滤条件
  2. struct resbuf* filter = acutBuildList(RTDXF0, _T("LWPOLYLINE"), RTNONE);
  3. ads_name ss;
  4. // 提示用户选择二个多边形
  5. acutPrintf(_T("\n请选择二个多边形(闭合多段线):\n"));
  6. int res = acedSSGet(NULL, NULL, NULL, filter, ss);
  7. // 释放缓冲区链表
  8. acutRelRb(filter);
  9. // 计时开始
  10. DWORD start, end;
  11. start = GetTickCount();
  12. // 如果取消了选择或者选择条件不符合
  13. if (res != RTNORM)
  14. {
  15.     acutPrintf(_T("\n没有选择二个多边形(闭合多段线)!"));
  16.     return;
  17. }
  18. // 选择集个数
  19. Adesk::Int32 length;
  20. acedSSLength(ss, &length);
  21. if (length != 2)
  22. {
  23.     acutPrintf(_T("\n必须选择二个多边形(闭合多段线)!"));
  24.     // 释放选择集
  25.     acedSSFree(ss);
  26.     return;
  27. }
  28. // 第一、二个多边形顶点集合,交集顶点集合
  29. AcGePoint3dArray poly1Pts, poly2Pts, interPolyPts;
  30. // 错误状态码
  31. Acad::ErrorStatus es;
  32. // 图元名
  33. ads_name eame1, eame2;
  34. acedSSName(ss, 0, eame1);
  35. acedSSName(ss, 1, eame2);
  36. // 释放选择集
  37. acedSSFree(ss);
  38. // 图元名转换为实体ID
  39. AcDbObjectId obj1Id, obj2Id;
  40. es = acdbGetObjectId(obj1Id, eame1);
  41. es = acdbGetObjectId(obj2Id, eame2);
  42. // 获取多边形顶点,并加入集合
  43. es = GetPolylineVertPts(obj1Id, poly1Pts);
  44. es = GetPolylineVertPts(obj2Id, poly2Pts);
  45. MPolygon p1, p2;
  46. Edge temp;
  47. // 第一个多边形
  48. for (int i = 0; i  interPts;
  49. MPolygon::SolveSub(p1, p2, interPts);  // 差集
  50. if (interPts.size() > 0)
  51. {
  52.     for (int i = 0; i  0)
  53.         {
  54.             int numVertices = pts.length();
  55.             AcDbPolyline* pPoly = new AcDbPolyline(numVertices);
  56.             for (int j = 0; j addVertexAt(j, pt2d, 0, 0, 0);
  57.             }
  58.             pPoly->setColorIndex(1);
  59.             pPoly->setClosed(TRUE);
  60.             pPoly->setConstantWidth(10);
  61.             AcDbBlockTable* pBlkTbl = NULL;
  62.             acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlkTbl, AcDb::kForRead);
  63.             AcDbBlockTableRecord* pBlkTblRcd = NULL;
  64.             pBlkTbl->getAt(ACDB_MODEL_SPACE, pBlkTblRcd, AcDb::kForWrite);
  65.             pBlkTbl->close();
  66.             pBlkTblRcd->appendAcDbEntity(pPoly);
  67.             pBlkTblRcd->close();
  68.             pPoly->close();
  69.         }
  70.     }
  71. }
  72. // 结束计时
  73. end = GetTickCount() - start;
  74. acutPrintf(_T("\n数学法用时: %d 毫秒"), end);
交并差所需的类见以下附件PolygonOAUtil.h、PolygonOAUtil.cpp
PolygonOAUtil.h头文件
  1. /// @file 多边形叠加分析(交并差)
  2. /// @date 2021-12-08
  3. /// @version v1.0
  4. #pragma once
  5. #include [i]
  6. #include
  7. #include
  8. using namespace std;
  9. /////////////////////////////////////////////////////////////////
  10. // Point 类 : 实现多边形点的存储,并记录点的性质。
  11. class Point
  12. {
  13. public:
  14.     // 存储多边形顶点的横坐标, 纵坐标
  15.     double x, y;
  16.     // 重构 Point 类的构造函数
  17.     Point(double x = 0, double y = 0) : x(x), y(y) {}
  18.     // 重构类的=运算
  19.     Point& operator=(const Point& b);
  20.     // 重构类的 circle_edge;
  21.     // 用来表示该环是内环还是外环
  22.     int type;  // 好像 type 无作用
  23.     // 重构 Circle 类的构造函数
  24.     Circle();
  25.     // 初始化 Circle 类对象的各个成员变量,避免因未初始化而引起的不知名错误
  26.     void init();
  27.     // 判断点是否在线段之上
  28.     static bool PointAboveSegment(Point p, Edge e);
  29. };
  30. /////////////////////////////////////////////////////////////////
  31. // MPolygon类:实现多边形的存储,并记录多边形的性质。
  32. class MPolygon
  33. {
  34. public:
  35.     // 存储多边形的外环
  36.     Circle external_circle;
  37.     // 存储多边形的内环
  38.     vector internal_circle;
  39.     // 重构 MPolygon 类的构造函数
  40.     MPolygon();
  41.     // 初始化 MPolygon 类对象的各个成员变量,避免因未初始化而引起的不知名错误
  42.     void init();
  43.     // 计算位于点p下方的另一多边形边的条数
  44.     int calc(Point p, const MPolygon B);
  45.     // 判断另一多边形中是否有边e
  46.     bool finde(Edge e, const MPolygon B);
  47.     // 判断内边还是外边
  48.     void getinout(const MPolygon B);
  49.     // 判断奇边还是偶边
  50.     void getodd();
  51.     // 得到简单边,作用是当前多边形的边与第二个多边形的边存在的交点插入当前多边形中
  52.     // 并重构当前多边形的边
  53.     void getSimpleEdge(const MPolygon B);
  54.     // 计算两个多边形交集
  55.     static int SolveAnd(MPolygon p1, MPolygon p2, vector& interPts);
  56.     // 计算两个多边形并集
  57.     static int SolveOr(MPolygon p1, MPolygon p2, vector& interPts);
  58.     // 计算两个多边形差集
  59.     static int SolveSub(MPolygon p1, MPolygon p2, vector& interPts);
  60. };
http://bbs.mjtd.com/forum.php?mod=attachment&aid=MTE3MTY0fGM1N2U4ZjY3NzkzMGQyYTAzYmRmMDkyMGY3NjZlOGFlfDE2NTkwODg3ODU%3D&request=yes&_f=.rar

本帖以下内容被隐藏保护;需要你回复后,才能看到!

游客,如果您要查看本帖隐藏内容请回复
回复

使用道具 举报

12

主题

51

帖子

7

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
99
发表于 2021-12-13 15:53:00 | 显示全部楼层
把每个多边形转为面域, 然后用面域的ARX的布尔函数求得也是可以的
回复

使用道具 举报

2

主题

36

帖子

7

银币

初来乍到

Rank: 1

铜币
44
发表于 2021-12-14 08:24:00 | 显示全部楼层
大佬和顾老师的ID很像啊
回复

使用道具 举报

11

主题

284

帖子

30

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
309
发表于 2021-12-14 10:12:00 | 显示全部楼层
来支持楼主一下,感谢分享c+源码
回复

使用道具 举报

0

主题

278

帖子

30

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
259
发表于 2022-2-12 22:58:00 | 显示全部楼层

来支持楼主一下,感谢分享c+源码
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2025-2-4 03:50 , Processed in 0.432681 second(s), 65 queries .

© 2020-2025 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表