测试结果:这个是按0.1,0.1,0.1,0.3,0.4的比例划分的。

插件描述:这个插件主要是选择一个多段线poly,设置poly的close属性为true,在poly任意一侧画一条长线line(line画的时候不能与poly相交),找到line的垂直向量p'yXl,这个pyXl是要往与poly能相交的方向。在找到这个line与poly相切的时候。然后取每次平移的步进值bujin,因为这个poly的总面积有大有小,所以我是取总面积totaArea/2000在开方,如果这个bujin<=1,则直接取1,这样对于面积很大的poly也不需要平移很多次。然后就是利用acedTraceBoundary函数来获取平移后的
切线与poly形成的封闭多段线pl,求这个pl的面积是否大与按比例分割后的面积。

需要注意的地方:在使用acedTraceBoundary的时候,必须确认poly和平移的切线都是close掉的,不然无法求出pl。如果没有acedTraceBoundary函数,可以这样:

//ads_point pt = { seedPoint.x,seedPoint.y,seedPoint.z };
//acedCommandS(RTSTR, L"-boundary", RTPOINT, pt, RTSTR, L"", RTNONE);
//acdbEntLast(pent);
////acedRedraw(pent, 3);
//AcDbObjectId eId; //acdbGetObjectId(eId, pent); //AcDbPolyline * pEnt = NULL; //ErrorStatus es = acdbOpenObject(pEnt, eId, AcDb::OpenMode::kForWrite);

来获得封闭的多段线,然后在求面积。

下面给出详细代码:
求pyXl:

AcGeVector3d CAreaFenGe::GetDirection()
{
//l2pt和l1pt是在poly侧边画的线的端点
AcGeVector3d lineDirc = l2Pt - l1Pt;
AcGeVector3d lineDirc2 = l2Pt - l1Pt; AcGePoint3d centerPt((l2Pt.x + l1Pt.x) / , (l2Pt.y + l1Pt.y) / , );
AcGePoint3d ptCloset; poly->getClosestPointTo(centerPt, ptCloset, false); AcDbLine *line1 = AcDbLine::cast(line->clone());
AcDbLine *line2 = AcDbLine::cast(line->clone());
double len = ptCloset.distanceTo(centerPt); AcGeVector3d pyXl1 = lineDirc.rotateBy(- * CMathUtil::PI() / , AcGeVector3d::kZAxis);
AcGeVector3d pyXl2 = lineDirc2.rotateBy(CMathUtil::PI() / , AcGeVector3d::kZAxis); line1->transformBy(AcGeMatrix3d::translation(pyXl1.normal()*len*1.5));
line2->transformBy(AcGeMatrix3d::translation(pyXl2.normal()*len*1.5));
AcGePoint3dArray p3dArr1, p3dArr2; poly->intersectWith(line1, AcDb::Intersect::kExtendArg, p3dArr1, , );
poly->intersectWith(line2, AcDb::Intersect::kExtendArg, p3dArr2, , ); if (p3dArr1.length() > ) {
pyXl = pyXl1;
}
else if(p3dArr2.length()>){
pyXl = pyXl2;
}
else {
pyXl = AcGeVector3d(, -, );//这个可以注释掉
}
delete line1;
line1 = NULL;
delete line2;
line2 = NULL; return pyXl;
}

获得切线:

//得到切线
AcGePoint3d CAreaFenGe::GetQieDian(AcDbLine * &line1)
{ line1 = new AcDbLine(l1Pt, l2Pt); AcGePoint3dArray ptArr; while (ptArr.length() < ) { poly->intersectWith(line1, AcDb::Intersect::kOnBothOperands, ptArr, , ); line1->transformBy(AcGeMatrix3d::translation(pyXl.normal() * )); }
poly->close(); if (ptArr.length() > )
return ptArr[];
else
return AcGePoint3d::kOrigin; }

得到面积:

bool  CAreaFenGe::GetPyPolyline(AcGePoint3d seedPoint, double & a)
{ AcDbVoidPtrArray ptrArr;
ErrorStatus es = acedTraceBoundary(seedPoint, false, ptrArr); if (es != Acad::eOk) {
acutPrintf(L"\nboundary=%d", es);
return false;
} AcDbPolyline * pl = NULL;
pl = (AcDbPolyline*)ptrArr[]; pl->setColorIndex(); pl->getArea(a); pl->erase();
pl->close();
pl = NULL;
return true; }

主要步骤:

void CAreaFenGe::Command()
{ ErrorStatus es;
AcDbLine * lQieXian = NULL;
AcGePoint3d ptQieDian = GetQieDian(lQieXian); acutPrintf(L"\nptQieDian=[%.2f,%.2f,%.2f]", ptQieDian.x, ptQieDian.y, ptQieDian.z); ptQieDian=ptQieDian.transformBy(AcGeMatrix3d::translation(pyXl.normal() * ));
acutPrintf(L"\nptQieDian2=[%.2f,%.2f,%.2f]", ptQieDian.x, ptQieDian.y, ptQieDian.z); if (ptQieDian.x == && ptQieDian.y == ) {
return;
}
double bujin = sqrt(totalArea * / ); if (bujin <= ) {
bujin = ;
} AcDbObjectId qxId;
lQieXian->transformBy(AcGeMatrix3d::translation(pyXl.normal() * bujin*)); es = acdbOpenObject(poly, plId, AcDb::kForRead); AcGePoint3dArray ptJdArr; poly->intersectWith(lQieXian, AcDb::Intersect::kOnBothOperands, ptJdArr, , ); if (ptJdArr.length() >= ) { ptQieDian=AcGePoint3d((ptJdArr[].x+ ptJdArr[].x)/, (ptJdArr[].y + ptJdArr[].y) / ,); ptQieDian= ptQieDian.transformBy(AcGeMatrix3d::translation(pyXl.normal() * -bujin*1.5)); }
poly->close(); qxId = CDwgDataBaseUtil::PostToModelSpace(lQieXian); lQieXian->close(); lQieXian = NULL; //AcDbPolyline * ptPy = new AcDbPolyline(); //ptPy->setColorIndex(5); //AcDbObjectId ptId; AcGePoint3dArray ptJdArr2; for (int i = ; i < (int)vecArea.size(); i++)
{ AcGePoint3d ptCopyQd = ptQieDian; double a = 0.0; while (a < vecArea[i]) { bool flag = GetPyPolyline(ptQieDian, a); if (!flag) {
return;
}
es = acdbOpenObject(lQieXian, qxId, AcDb::kForWrite);
lQieXian->transformBy(AcGeMatrix3d::translation(pyXl.normal() * bujin)); ptJdArr2.removeAll(); es = acdbOpenObject(poly, plId, AcDb::kForRead);
poly->intersectWith(lQieXian, AcDb::Intersect::kExtendArg, ptJdArr2, , ); poly->close(); if (ptJdArr2.length() < ) { lQieXian->close();
break; } lQieXian->close(); } acdbOpenObject(lQieXian, qxId, AcDb::kForWrite); es = acdbOpenObject(poly, plId, AcDb::kForRead); ptJdArr.removeAll(); poly->intersectWith(lQieXian, AcDb::Intersect::kExtendArg, ptJdArr, , ); AcGePoint3d preCenter;
if (ptJdArr.length() >= ) { AcDbLine* lFg = new AcDbLine(ptJdArr[], ptJdArr[]); preCenter = AcGePoint3d((ptJdArr[].x + ptJdArr[].x) / , (ptJdArr[].y + ptJdArr[].y) / , );
lFg->setColorIndex(); CDwgDataBaseUtil::PostToModelSpace(lFg); lFg->close(); }
else { poly->close();
lQieXian->erase();
lQieXian->close();
lQieXian = NULL;
//ptId = CDwgDataBaseUtil::PostToModelSpace(ptPy);
return; } poly->close(); AcDbPolyline *pCopyQx = (AcDbPolyline*)lQieXian->clone(); pCopyQx->transformBy(AcGeMatrix3d::translation(pyXl.normal() *bujin)); if (i != (int)vecArea.size() - ) { es = acdbOpenObject(poly, plId, AcDb::kForRead); ptJdArr.removeAll(); poly->intersectWith(pCopyQx, AcDb::Intersect::kExtendArg, ptJdArr, , ); if (ptJdArr.length() >= ) {
ptQieDian = AcGePoint3d((ptJdArr[].x + ptJdArr[].x) / , (ptJdArr[].y + ptJdArr[].y) / , ); ptQieDian = AcGePoint3d((preCenter.x + ptQieDian.x) / , (preCenter.y + ptQieDian.y) / , ); }
qxId = CDwgDataBaseUtil::PostToModelSpace(pCopyQx); pCopyQx->close();
poly->close();
pCopyQx = NULL;
}
lQieXian->erase();
lQieXian->close();
lQieXian = NULL; //当运行到最后一个面积时,就不复制了
if (i == (int)vecArea.size() - ) { delete pCopyQx;
pCopyQx = NULL; break;
}
} /*if (ptId.isNull()) {
ptId = CDwgDataBaseUtil::PostToModelSpace(ptPy);
ptPy->close();
}*/
}

构造函数:

CAreaFenGe::CAreaFenGe(ACHAR *fenGeStr, AcDbPolyline *&p, AcDbLine *&l)
{ vector<CString> vec; CStringUtil::Split(W2T(fenGeStr), L",", vec, false); for (int i = ; i < (int)vec.size(); i++)
{
vecFenGe.push_back(_wtof(vec.at(i)));
}
this->poly = p;
this->line = l; l1Pt = l->startPoint();
l2Pt = l->endPoint(); if (poly->isClosed() == false) {
poly->setClosed(true);
} poly->getArea(totalArea); for (int i = ; i < (int)vecFenGe.size(); i++)
{
vecArea.push_back(totalArea*vecFenGe.at(i));
acutPrintf(L"%.2f", vecArea[i]);
}
GetDirection();
plId = poly->objectId();
}

objectarx 按比例分割封闭多段线的更多相关文章

  1. Objectarx 相交矩形求并集 面域转多段线

    测试结果: 主要思路:拾取一个点作为矩形的插入点,分别以该点进行两次jig操作,就能得到白色的两个相交的polyline,之后需要变成红色的封闭多段线.做法就是:求出两个白色矩形的面域,然后通过boo ...

  2. objectarx 多段线自交检查

    只支持直线段的多段线检查,因为主要用了初中的知识,一元一次方程求交点,详细的说就是,把多段线上相邻的两个点构成一条直线段,然后每条直线段与剩余的直线段求交点,一条直线段就代表一个一元一次方程,知道两点 ...

  3. objectarx 填充的分割

    主要思路:找到填充边界集合:vecBo,然后把面积最大的边界找出来:bo1,用分割曲线和bo1通过boundary命令构成两个新的最大封闭边界,左边的记为 boLeft(红色部分),右边的记为boRi ...

  4. ArcGIS AddIn 图斑比例分割工具,调用捕捉功能

    最近做一个图斑按比例分割的工具,需要绘制一条用以切割的方向线,通过Tool的方式实现 绘制时希望能够使用捕捉功能,查阅相关资料如下: 使用该文章,第Implementing snapping in a ...

  5. arcgis 按面积分割, 按比例分割面积,按等份批量面积分割工具

    arcgis 按面积分割, 按比例分割面积,按等份批量面积分割工具 视频下载:https://yunpan.cn/cvujkpKIqwccn  访问密码 e9f4

  6. Java 直线、多段线画板 PaintJFrame (整理)

    package demo; import java.awt.BorderLayout; import java.awt.Color; import java.awt.FlowLayout; impor ...

  7. Cesium实现文字、点、多段线、多边形的实时绘制

    背景知识 点.线.面以及文字的实时绘制是GIS很重要的一个功能,是用户对感兴趣区域标注的业务需要.同时Cesium提供了点.线(多段线).面及文字(label)绘制的接口,绘制方式总共有两种,一种是通 ...

  8. 4、c++ Arx二次开发创建多段线

    一.本节课程 c++ Arx二次开发创建多段线 二.本节要讲解的知识点 如何应用C++ ARX二次开发创建多段线(AcDbPolyline.AcDb2dPolyLine.AcDb3dPolyline的 ...

  9. CAD交互绘制多段线(网页版)

    多段线又被称为多义线,表示一起画的都是连在一起的一个复合对象,可以是直线也可以是圆弧并且它们还可以加不同的宽度. 主要用到函数说明: _DMxDrawX::DrawLine 绘制一个直线.详细说明如下 ...

随机推荐

  1. P1052 国王放置问题

    题目描述 在n*m的棋盘上放置k个国王,要求k个国王互相不攻击,有多少种不同的放置方法.假设国王放置在第(x,y)格,国王的攻击的区域是:(x-1,y-1), (x-1,y),(x-1,y+1),(x ...

  2. linux 读者/写者自旋锁

    内核提供了一个自旋锁的读者/写者形式, 直接模仿我们在本章前面见到的读者/写者旗标. 这些锁允许任何数目的读者同时进入临界区, 但是写者必须是排他的存取. 读者写者锁有 一个类型 rwlock_t, ...

  3. post提交方式为什么要序列化,而Get提交方式就不用?序列化做了什么?

    这是因为后台能够直接处理的数据格式,是一种经过序列化的键值对数据,比如前端要向后台提交三个参数,分别是a=1,b=2,c=3,那么后台接收到的数据就应该是a=1&b=2&c=3(可以看 ...

  4. H3C配置热键--hotkey---系统视图

    Hotkey作用 hotkey 命令用来为某一快捷键指定相应的命令行. undo hotkey 命令用来恢复系统的默认值. —————————————————————————————————————— ...

  5. Maven 运行 tomcat:run 时出现 Unable to compile class for JSP...

    近来无事便去看了看神奇的 Maven , 但写第一个 Hello,World 就非常不友好的怼给我一个 500, 很是郁闷; 开发环境: JDK1.8, Maven 3.5 项目目录: \maven_ ...

  6. Libra和中国央行数字货币(DCEP)的对比

    最近偶然和朋友讨论起Libra,对Libra和央行的数字货币方案很感兴趣.梳理了阅读资料(参考见文末)和自己的思考,发知乎留个记录. Libra 是什么? 无国界货币 + 为全球数十亿人服务的金融基础 ...

  7. To learns

    1. avro https://www.jianshu.com/p/ecbb607809c4

  8. 2020年. NET Core面试题

    第1题,什么是ASP net core? 首先ASP net core不是 asp net的升级版本.它遵循了dot net的标准架构, 可以运行于多个操作系统上.它更快,更容易配置,更加模块化,可扩 ...

  9. $[NOIp2017]$ 逛公园 $dp$/记搜

    \(Des\) 给定一个有向图,起点为\(1\),终点为\(n\),求和最短路相差不超过\(k\)的路径数量.有\(0\)边.如果有无数条,则输出\(-1\). \(n\leq 10^5,k\leq ...

  10. Theia架构

    上一篇:Theia——云端和桌面版的IDE 架构概述 本节描述了Theia的整体架构. Theia被设计为一个可以在本地运行的桌面应用程序,也可以在浏览器和远程服务器之间工作.为了支持这两种工作方式, ...