多边形叠加分析(交并差)
MFC 的多边形叠加分析(交并差)见原帖网址:arx的多边形叠加分析(交并差)效果图:
http://bbs.mjtd.com/forum.php?mod=attachment&aid=MTE3MTYxfDA5YmM3YmY5YTFmMzhkZGQ3YzNmMzZlMWY3Mjg2MDExfDE2NTkwODg3ODU%3D&request=yes&_f=.gif
arx 的不支持有弧段的多边形。
数学法计算交集与面域法计算交集的时间比较:
数学法用时: 0 毫秒
面域法用时: 2937毫秒
获取多段线顶点坐标,并加入点集合中
复制代码多边形叠加分析(交集) 测试
复制代码多边形叠加分析(并集) 测试
复制代码多边形叠加分析(差集) 测试
// 创建多段线过滤条件
struct resbuf* filter = acutBuildList(RTDXF0, _T("LWPOLYLINE"), RTNONE);
ads_name ss;
// 提示用户选择二个多边形
acutPrintf(_T("\n请选择二个多边形(闭合多段线):\n"));
int res = acedSSGet(NULL, NULL, NULL, filter, ss);
// 释放缓冲区链表
acutRelRb(filter);
// 计时开始
DWORD start, end;
start = GetTickCount();
// 如果取消了选择或者选择条件不符合
if (res != RTNORM)
{
acutPrintf(_T("\n没有选择二个多边形(闭合多段线)!"));
return;
}
// 选择集个数
Adesk::Int32 length;
acedSSLength(ss, &length);
if (length != 2)
{
acutPrintf(_T("\n必须选择二个多边形(闭合多段线)!"));
// 释放选择集
acedSSFree(ss);
return;
}
// 第一、二个多边形顶点集合,交集顶点集合
AcGePoint3dArray poly1Pts, poly2Pts, interPolyPts;
// 错误状态码
Acad::ErrorStatus es;
// 图元名
ads_name eame1, eame2;
acedSSName(ss, 0, eame1);
acedSSName(ss, 1, eame2);
// 释放选择集
acedSSFree(ss);
// 图元名转换为实体ID
AcDbObjectId obj1Id, obj2Id;
es = acdbGetObjectId(obj1Id, eame1);
es = acdbGetObjectId(obj2Id, eame2);
// 获取多边形顶点,并加入集合
es = GetPolylineVertPts(obj1Id, poly1Pts);
es = GetPolylineVertPts(obj2Id, poly2Pts);
MPolygon p1, p2;
Edge temp;
// 第一个多边形
for (int i = 0; iinterPts;
MPolygon::SolveSub(p1, p2, interPts);// 差集
if (interPts.size() > 0)
{
for (int i = 0; i0)
{
int numVertices = pts.length();
AcDbPolyline* pPoly = new AcDbPolyline(numVertices);
for (int j = 0; j addVertexAt(j, pt2d, 0, 0, 0);
}
pPoly->setColorIndex(1);
pPoly->setClosed(TRUE);
pPoly->setConstantWidth(10);
AcDbBlockTable* pBlkTbl = NULL;
acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlkTbl, AcDb::kForRead);
AcDbBlockTableRecord* pBlkTblRcd = NULL;
pBlkTbl->getAt(ACDB_MODEL_SPACE, pBlkTblRcd, AcDb::kForWrite);
pBlkTbl->close();
pBlkTblRcd->appendAcDbEntity(pPoly);
pBlkTblRcd->close();
pPoly->close();
}
}
}
// 结束计时
end = GetTickCount() - start;
acutPrintf(_T("\n数学法用时: %d 毫秒"), end);交并差所需的类见以下附件PolygonOAUtil.h、PolygonOAUtil.cpp
PolygonOAUtil.h头文件
/// @file 多边形叠加分析(交并差)
/// @date 2021-12-08
/// @version v1.0
#pragma once
#include
#include
#include
using namespace std;
/////////////////////////////////////////////////////////////////
// Point 类 : 实现多边形点的存储,并记录点的性质。
class Point
{
public:
// 存储多边形顶点的横坐标, 纵坐标
double x, y;
// 重构 Point 类的构造函数
Point(double x = 0, double y = 0) : x(x), y(y) {}
// 重构类的=运算
Point& operator=(const Point& b);
// 重构类的 circle_edge;
// 用来表示该环是内环还是外环
int type;// 好像 type 无作用
// 重构 Circle 类的构造函数
Circle();
// 初始化 Circle 类对象的各个成员变量,避免因未初始化而引起的不知名错误
void init();
// 判断点是否在线段之上
static bool PointAboveSegment(Point p, Edge e);
};
/////////////////////////////////////////////////////////////////
// MPolygon类:实现多边形的存储,并记录多边形的性质。
class MPolygon
{
public:
// 存储多边形的外环
Circle external_circle;
// 存储多边形的内环
vector internal_circle;
// 重构 MPolygon 类的构造函数
MPolygon();
// 初始化 MPolygon 类对象的各个成员变量,避免因未初始化而引起的不知名错误
void init();
// 计算位于点p下方的另一多边形边的条数
int calc(Point p, const MPolygon B);
// 判断另一多边形中是否有边e
bool finde(Edge e, const MPolygon B);
// 判断内边还是外边
void getinout(const MPolygon B);
// 判断奇边还是偶边
void getodd();
// 得到简单边,作用是当前多边形的边与第二个多边形的边存在的交点插入当前多边形中
// 并重构当前多边形的边
void getSimpleEdge(const MPolygon B);
// 计算两个多边形交集
static int SolveAnd(MPolygon p1, MPolygon p2, vector& interPts);
// 计算两个多边形并集
static int SolveOr(MPolygon p1, MPolygon p2, vector& interPts);
// 计算两个多边形差集
static int SolveSub(MPolygon p1, MPolygon p2, vector& interPts);
};http://bbs.mjtd.com/forum.php?mod=attachment&aid=MTE3MTY0fGM1N2U4ZjY3NzkzMGQyYTAzYmRmMDkyMGY3NjZlOGFlfDE2NTkwODg3ODU%3D&request=yes&_f=.rar
**** Hidden Message ***** 把每个多边形转为面域, 然后用面域的ARX的布尔函数求得也是可以的 大佬和顾老师的ID很像啊 来支持楼主一下,感谢分享c+源码
来支持楼主一下,感谢分享c+源码
页:
[1]