主要思路:找到填充边界集合:vecBo,然后把面积最大的边界找出来:bo1,用分割曲线和bo1通过boundary命令构成两个新的最大封闭边界,左边的记为 boLeft(红色部分),右边的记为boRight(绿色部分),在vecBo边界集合分开为:boLeft内部的边界,和boRight内部的边界。这样在分别填充的时候,就能有正确的填充边界集合。

下面放出代码:
通过选择填充求得填充边界集合:

static void GetHatchBo(AcDbHatch *pHatch,vector<AcDbEntity*>&vecBo)
{
Acad::ErrorStatus es; Adesk::Int32 LoopType; AcGeVoidPointerArray edgeptrAry;
AcGeIntArray edgeTypesAry; AcGePoint2dArray vertices;
AcGeDoubleArray bulges; //获得填充边界的数目
int LoopNum = pHatch->numLoops(); for (int i = ; i < LoopNum; i++)
{
//获取边界类型
LoopType = pHatch->loopTypeAt(i);
//如果边界是多义线
if (LoopType & AcDbHatch::kPolyline)
{
//取得边界定义数据(polyline)的顶点数组和凸度数组,它们是一一对应的
es = pHatch->getLoopAt(i, LoopType, vertices, bulges);
acutPrintf(L"\n多段线");
//是不是根据这些顶点数组和凸度数组构造一条AcDb多义线取决于你
AcDbPolyline *pl = new AcDbPolyline(); GetPolyline(vertices, bulges, pl); vecBo.push_back(pl);
}
else
{
//几乎可以取得除polyline外的所有边界定义数据
//第三个参数返回值是无值指针数组
//第四个参数返回值是组成边界的每一条边的类型
//它们也是一一对应的关系
es = pHatch->getLoopAt(i, LoopType, edgeptrAry, edgeTypesAry); //遍历,因为每一条边界又可能由多种AcGe曲线构成
for (int j = ; j < edgeTypesAry.length(); j++)
{ if (edgeTypesAry[j] == AcDbHatch::kLine)//直线
{
AcGeLineSeg2d *LnSeg = (AcGeLineSeg2d *)edgeptrAry[j];
acutPrintf(L"\n直线");
AcGePoint2d pt1 = LnSeg->startPoint();
AcGePoint2d pt2 = LnSeg->endPoint(); AcDbLine *line = new AcDbLine(AcGePoint3d(pt1.x,pt1.y,), AcGePoint3d(pt2.x, pt2.y, )); vecBo.push_back(line);
}
//圆弧
else if (edgeTypesAry[j] == AcDbHatch::kCirArc)
{
AcGeCircArc2d *cirArc = (AcGeCircArc2d *)edgeptrAry[j];
acutPrintf(L"\n圆弧");
//可以根据数学圆弧构造相应的AcDb圆弧,取决于你(以下同)
AcGePoint2d center = cirArc->center();
double ra = cirArc->radius();
double angle1 = cirArc->startAng();
double angle2 = cirArc->endAng();
AcDbCircle *cir = new AcDbCircle(AcGePoint3d(center.x, center.y, ), AcGeVector3d::kZAxis, ra); vecBo.push_back(cir); }
else if (edgeTypesAry[j] == AcDbHatch::kEllArc)//椭圆弧
{
AcGeEllipArc2d *ellArc = (AcGeEllipArc2d *)edgeptrAry[j];
acutPrintf(L"\n椭圆弧"); AcGePoint2d center = ellArc->center();
AcGeVector2d majorVec = ellArc->majorAxis();
double angle1 = ellArc->startAng();
double angle2 = ellArc->endAng();
double rad = ellArc->majorRadius();
double rad2 = ellArc->minorRadius(); AcDbEllipse *ell = new AcDbEllipse(AcGePoint3d(center.x, center.y, ),
AcGeVector3d::kZAxis, AcGeVector3d(majorVec.x,majorVec.y,), rad / rad2, angle1, angle2);
vecBo.push_back(ell);
}
else if (edgeTypesAry[j] == AcDbHatch::kSpline)//NURBS曲线
{
AcGeNurbCurve2d *spline = (AcGeNurbCurve2d *)edgeptrAry[j];
acutPrintf(L"\nNURBS曲线"); AcDbSpline * spl = NULL; createSpline(*spline, spl, ); vecBo.push_back(spl); }
}
} vertices.removeAll();
bulges.removeAll();
edgeptrAry.removeAll();
edgeTypesAry.removeAll();
}
}

获得填充边界集合

分割曲线构造新多段线:

if (pEnt2->isA() == AcDbPolyline::desc()) {

            AcDbPolyline * plTemp = AcDbPolyline::cast(pEnt2);

            AcGeDoubleArray dbArr;
AcGePoint2dArray pt2dArr; int indexS = , indexE = ; GetCollOfPl(plTemp, dbArr, pt2dArr);
//获得两个交点的索引用来构造新的多段线
GetIndexOfPl(plTemp, pt2dArr, ptArr, indexS, indexE); AcDbPolyline *newPl = new AcDbPolyline(); newPl->addVertexAt(newPl->numVerts(), AcGePoint2d(ptArr[].x, ptArr[].y), , , ); for (int i=indexS;i<=indexE;i++)
{
newPl->addVertexAt(newPl->numVerts(), pt2dArr[i], dbArr[i], , ); }
newPl->addVertexAt(newPl->numVerts(), AcGePoint2d(ptArr[].x, ptArr[].y), , , ); newPl->setColorIndex(); PostToModelSpace(newPl); newPl->close(); }

截取分隔曲线

构造左右边界:红色部分最大边界和绿色部分最大边界

static bool  GetBoundary(const AcGePoint3d & seedPoint, AcDbVoidPtrArray& ptrArr)
{ ErrorStatus es = acedTraceBoundary(seedPoint, false, ptrArr); if (es != Acad::eOk) {
acutPrintf(L"\nboundary=%d", es);
return false;
}
return true;
}

判断vecBo边界集合的边界是否在左右边界内部:
主要是获得内部图形的点集,然后把左边边界内部的一点分别与这个点集中的点构成直线,如果直线和左边边界相交时有1个以上交点,就说明这个边界不在左边界内部。

static bool JudgeXj(CONST AcGePoint3dArray & ptArr, AcDbEntity *pEnt,const AcGePoint3d &innerPt) {

        AcDbLine * l = new AcDbLine();

        l->setStartPoint(innerPt);

        AcGePoint3dArray ptTemp;

        for (int i = ; i < ptArr.length(); i++)
{
l->setEndPoint(ptArr[i]); l->intersectWith(pEnt, AcDb::kOnBothOperands, ptTemp); if (ptTemp.length() >= ) { delete l;
l = NULL; return true;
}
}
return false;
}

判断边界是否在左边边界内部

完整代码见附件:

objectarx 填充的分割的更多相关文章

  1. objectarx 按比例分割封闭多段线

    测试结果:这个是按0.1,0.1,0.1,0.3,0.4的比例划分的. 插件描述:这个插件主要是选择一个多段线poly,设置poly的close属性为true,在poly任意一侧画一条长线line(l ...

  2. Node.js:Buffer浅谈

    Javascript在客户端对于unicode编码的数据操作支持非常友好,但是对二进制数据的处理就不尽人意.Node.js为了能够处理二进制数据或非unicode编码的数据,便设计了Buffer类,该 ...

  3. Matlab命令系列之目录操作

    Matlab命令系列之目录操作 filesep 用于返回当前平台的目录分隔符,Windows是反斜杠(),Linux是斜杠(/).有时此命令结合ispc命令使用,可以灵活的设置目录分割符. fullf ...

  4. Matlab命令——目录操作(windows&Linux)

    Matlab命令——目录操作(windows&Linux) 1. filesep用于返回当前平台的目录分隔符,Windows是反斜杠(\),Linux是斜杠(/).有时此命令结合ispc命令使 ...

  5. [Google Guava] 6-字符串处理:分割,连接,填充

    原文链接 译文链接 译者:沈义扬,校对:丁一 连接器[Joiner] 用分隔符把字符串序列连接起来也可能会遇上不必要的麻烦.如果字符串序列中含有null,那连接操作会更难.Fluent风格的Joine ...

  6. sqlserver数据,将一行某一列字符串的值用“_”分割分别填充到这一行的其他列

    分割字符到列DECLARE @a VARCHAR(10)SET @a ='00G-2-1102'SELECT CHARINDEX('-',@a,CHARINDEX('-',@a))SELECT CHA ...

  7. Matlab的标记分水岭分割算法

    1 综述 Separating touching objects in an image is one of the more difficult image processing operation ...

  8. Shell文本处理 - 分割合并与过滤

    sort分类操作 示例文件 Boys in Company C:HK:192:2192 Alien:HK:119:1982 The Hill:KL:63:2972 Aliens:HK:532:4892 ...

  9. java:快速文件分割及合并

    文件分割与合并是一个常见需求,比如:上传大文件时,可以先分割成小块,传到服务器后,再进行合并.很多高大上的分布式文件系统(比如:google的GFS.taobao的TFS)里,也是按block为单位, ...

随机推荐

  1. ununtu 16.04 下的 VsCode 下载与安装

    Vscode发现用包下载显示找不到网页,于是只有继续折腾. 折腾如下: ubuntu-desktop You can update your system with unsupported packa ...

  2. 如何将EXCEL两列比较后不重复的数据复制到另一列上

    Q1:我有两列数据,需要做重复性比较,比较完后需要将不重复的数据提取出来自成一列,请问该如何操作? 假如你要比较A列与B列数据是否重复,应该有三种结果(即AB皆有,A有B无,B有A无),可在C列存放A ...

  3. mac下停止和启动mysql命令

    启动MySQL服务 sudo /usr/local/MYSQL/support-files/mysql.server start   停止MySQL服务 sudo /usr/local/mysql/s ...

  4. [从 0 开始的 Angular 生活]No.38 实现一个 Angular Router 切换组件页面(一)

    前言 今天是进入公司的第三天,为了能尽快投入项目与成为团队可用的战力,我正在努力啃官方文档学习 Angular 的知识,所以这一篇文章主要是记录我如何阅读官方文档后,实现这个非常基本的.带导航的网页应 ...

  5. Leetcode13_罗马数字转整数

    题目 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值I 1V 5X 10L 50C 100D 500M 1000例如, 罗马数字 2 写做 II ,即为两个并列的 1. ...

  6. EmguCV C# 安装入门教程

    EmguCv3的安装. EmguCv3下载网址 http://sourceforge.net/projects/emgucv/files/emgucv/3.0.0/ 推荐下载第一个: 点击direct ...

  7. 提前窥测奥斯卡颁奖信封中的谜底  ——Rothschild预测2014奥斯卡花落谁家

     --Rothschild预测2014奥斯卡花落谁家" title="提前窥测奥斯卡颁奖信封中的谜底  --Rothschild预测2014奥斯卡花落谁家"> 编者 ...

  8. 在CentOS安装CMake (CentOS7 64位适用)

    在CentOS安装CMake 转自:http://www.cnblogs.com/mophee/archive/2013/03/19/2969456.html 一.环境描述 1.系统:CentOS 6 ...

  9. tomcat启动不了的问题

    tomcat启动的几个问题 1.端口冲突 2.非端口冲突,需要加入配置host文件 日志文件: 解决办法:https://blog.csdn.net/u012949658/article/detail ...

  10. MyBatis SQL语句写法

    一.forEach 接口: public List<Entity> queryById(List<String> userids); 语法: <select id=&qu ...