黄色的线是天正建筑2014画出来的墙炸开后的样子,炸开后全是AcDbLine。可以看到这个黄色的线在拐弯处,交叉处会出现多余的小线段,并且是不连续的,或者是超出了缺口,想要把它转变成梁就需要考虑这些因素。

我的思路是这样的,第一步 过滤小于等于墙厚度的直线,这样多余的直线就会消失,之后保存剩下的线段到一个vector集合中。

for (int i = 0; i < ids.length(); i++)
{
AcDbLine * l = NULL; if (acdbOpenObject(l, ids[i], AcDb::kForWrite) == Acad::eOk) { double len = 0;
l->getDistAtPoint(l->endPoint(), len)
//根据要求有三种数值的墙厚度
if (len <queKou||len<queKou2||len<quekou3) {
l->erase();
l->close();
l = NULL;
}
else
{
vecLines.push_back(l);
}
}
}

第二步,把所有缺口封闭起来形成类似“#”这样的缺口,我采用的办法是,遍历直线集合,两两相交,如果有交点就延长至交点处,这里有个限制,那就是从线的端点到延长到交点的长度不超过1.5*quekou值并且交点确实是在延长线上而不是在直线的两个端点之间。

for (int ww = 0; ww < (int)vecLines.size(); ww++)
{
AcDbLine * l1 = vecLines[ww];
for (int j = ww + 1; j < (int)vecLines.size(); j++)
{
AcDbLine *l2 = vecLines[j]; l1->intersectWith(l2, AcDb::kOnBothOperands, temp1, 0, 0); if (1 == temp1.length()) { temp1.removeAll(); }
else {
l1->intersectWith(l2, AcDb::kExtendBoth, temp2, 0, 0); if (temp2.length() > 0) {
ExtendLine(l1, temp2[0]);
ExtendLine(l2, temp2[0]);
temp2.removeAll();
}
}
}
}
static void ExtendLine(AcDbLine * l1, const  AcGePoint3d & pt) {
AcGePoint3d pt11 = l1->startPoint();
AcGePoint3d pt12 = l1->endPoint();
double disO = pt11.distanceTo(pt12); double dis1 = pt11.distanceTo(pt);
double dis2 = pt12.distanceTo(pt); double max = (dis2 > dis1 ? dis2 : dis1); if (max > disO + 1.5*(queKou + queKou2 + quekou3) / 3 || max < disO) { return;
}
else { if (max==dis2) { l1->setStartPoint(pt); }
else {
l1->setEndPoint(pt);
} }
}

第三步削减类似“#”的口子,让它们变成类似互通的路口,我采取的方法是遍历两两相交,判断交点是否在线的两个端点之间,如果是,则进行消减,改变端点。

//削减
for (int ww = 0; ww < (int)vecLines.size(); ww++)
{
AcDbLine * l1 = vecLines[ww]; for (int j = ww + 1; j < (int)vecLines.size(); j++)
{
AcDbLine *l2 = vecLines[j];
//l1->intersectWith(l2, AcDb::kExtendBoth, temp2, 0, 0);
l1->intersectWith(l2, AcDb::kOnBothOperands, temp1, 0, 0); if (1 == temp1.length()) { CutLine(l1, temp1[0]);
CutLine(l2, temp1[0]);
temp1.removeAll();
}
}
}
static void CutLine(AcDbLine * l1, const  AcGePoint3d & pt) {
AcGePoint3d pt11 = l1->startPoint();
AcGePoint3d pt12 = l1->endPoint();
double disO = pt11.distanceTo(pt12); double dis1 = pt11.distanceTo(pt);
double dis2 = pt12.distanceTo(pt); if (disO > dis1&&disO > dis2) { if (dis1 <= (queKou + queKou2 + quekou3)/3&&dis2 <= (queKou + queKou2 + quekou3) / 3) { return; }
else { if (dis1 < dis2) {
l1->setStartPoint(pt);
}
else {
l1->setEndPoint(pt);
}
}
}
}

第四步,在第三步的时候会把边界的路口的线也给删了,所以就要补充边界缺口。这时剩下的缺口有个特点,那就是缺口对应的两条线是不会有交点的,利用这个特点就能解决问题。我是在交点处画一个圆,与圆相交的线构成集合,然后把这个集合中部任何线相交的直线找出来,进行延长相交,补充缺口。

//補充
temp1.removeAll();
temp2.removeAll();
AcGePoint3dArray ptArrAll;
ptArrAll.append(AcGePoint3d::kOrigin);
ptArrAll.removeAll(); for (int i = 0; i < (int)vecLines.size(); i++)
{
AcDbLine * l1 = vecLines[i]; ptArrAll.append(l1->startPoint());
ptArrAll.append(l1->endPoint()); } //acutPrintf(L"prePt=%d", ptArrAll.length());
double r = (queKou + queKou2 + quekou3) / 3*2;
for (int i=0;i<ptArrAll.length();i++)
{
AcGePoint3d ptCenter=ptArrAll[i]; AcDbCircle *cir = new AcDbCircle(ptCenter, AcGeVector3d::kZAxis, r); for (int j = i+1; j < ptArrAll.length(); j++) { AcGePoint3d pt2 = ptArrAll[j]; double dis = pt2.distanceTo(ptCenter); if (dis <= r) { ptArrAll.removeAt(j); } }
delete cir;
cir = NULL;
}
//acutPrintf(L"afterPt=%d", ptArrAll.length()); for (int i = 0; i < ptArrAll.length(); i++)
{
AcGePoint3d ptCenter = ptArrAll[i]; AcDbCircle *cir = new AcDbCircle(ptCenter, AcGeVector3d::kZAxis, r);
vector<AcDbLine*>vecLL;
for (int ww = 0; ww < (int)vecLines.size(); ww++)
{ AcDbLine * l1 = vecLines[ww]; l1->intersectWith(cir, AcDb::kOnBothOperands, temp1, 0, 0); if (temp1.length() > 0) { vecLL.push_back(l1);
temp1.removeAll(); } } delete cir;
cir = NULL; AcGeIntArray intArr; for (int m = 0; m < (int)vecLL.size(); m++)
{
AcDbLine * lT1 = vecLL[m]; for (int s = 0; s < (int)vecLL.size(); s++)
{
AcDbLine * lT2 = vecLL[s]; lT1->intersectWith(lT2, AcDb::kOnBothOperands, temp2, 0, 0); if (temp2.length() > 0) { intArr.append(m);
intArr.append(s); temp2.removeAll(); } } } for (int m = 0; m < (int)vecLL.size(); m++)
{
if (intArr.contains(m))
{
continue;
} AcDbLine * lT1 = vecLL[m]; for (int s = 0; s < (int)vecLL.size() ; s++)
{
if (intArr.contains(s)) { continue;
} AcDbLine * lT2 = vecLL[s]; lT1->intersectWith(lT2, AcDb::kExtendBoth, temp2, 0, 0);
//ptNJdAll.append(temp2[0]);
if (temp2.length() > 0) {
AcGePoint3d pt11 = lT1->startPoint();
AcGePoint3d pt12 = lT1->endPoint();
double disO = pt11.distanceTo(pt12); double dis1 = pt11.distanceTo(temp2[0]);
double dis2 = pt12.distanceTo(temp2[0]); double max1 = (dis2 > dis1 ? dis2 : dis1); AcGePoint3d pt21 = lT2->startPoint();
AcGePoint3d pt22 = lT2->endPoint();
double disO2 = pt21.distanceTo(pt22); double dis21 = pt21.distanceTo(temp2[0]);
double dis22 = pt22.distanceTo(temp2[0]); double max21 = (dis22 > dis21 ? dis22 : dis21); if (max1 < disO + 0.5*(queKou + queKou2 + quekou3))
{
if (max1 == dis2) { lT1->setStartPoint(temp2[0]);
}
else {
lT1->setEndPoint(temp2[0]);
}
}
if (max21 < disO2 + 0.5*(queKou + queKou2 + quekou3)) {
if (max21 == dis22) { lT2->setStartPoint(temp2[0]);
}
else {
lT2->setEndPoint(temp2[0]);
}
} temp2.removeAll();
} }
}
intArr.removeAll(); vecLL.clear();
}

最后在关闭实体

for (int i = 0; i < (int)vecLines.size(); i++)
{ vecLines[i]->setColorIndex(1); vecLines[i]->close(); }

objectarx 天正的墙转梁线的更多相关文章

  1. visual studio 2017安装教程以及各类问题解决方案

    文章的关键词和所含教程: VS2017安装/visual studio 2017安装/Xamarin/Android for visual studio 2017/VS2017找不到网站/VS2017 ...

  2. IFC文件解析

    什么是IFC? EXPRESS语言与IFC体系 一.IFC 1.IFC简介 IFC是一个数据交换标准, 用于不同系统交换和共享数据.当需要多个软件协同完成任务时, 不同系统之间就会出现数据交换和共享的 ...

  3. IFC文件介绍

    IFC是一个数据交换标准, 用于不同系统交换和共享数据. IFC是采用EXPRESS语言定义的实体关系模型,由几百个实体对象组成.实体对象包括建筑要素如IfcWall,几何元素如IfcExtruded ...

  4. 计算几何——判线段规范相交+最短路zoj1721

    枚举每个端点,然后i点j点连线作为一条路径,逐一判断这条路径是否可行即可 注意的地方:判一条线段是否可行,需要判其余线段是否和其相交,但是这个相交比较难判(因为会不规范相交),所以将问题转化为墙以外的 ...

  5. Abaqus 载荷分类(部分)

    目录 1. 集中载荷 1.1 集中载荷施加方法 1.2 定义集中跟随力 1.3 指定文件定义集中节点力 2. 分布载荷 2.1 分布载荷分类 3. 热载荷 3.1 模拟热辐射 3.2 直接定义热流量 ...

  6. 前端3D引擎-Cesium自定义动态材质

    本文代码基于Vue-cli4和使用WebGL的地图引擎Cesium,主要内容为三维场景下不同对象的动态材质构建. 参考了很多文章,链接附在文末. 为不同的几何对象添加动态材质 不知道这一小节的名称概况 ...

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

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

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

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

  9. objectarx 多段线自交检查

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

  10. objectarx之画多段线和画直线

    void CCommonFuntion::DrowPloyLine(AcGePoint2dArray& inputpoints){ if (inputpoints.length() < ...

随机推荐

  1. 掌上新闻随心播控,HarmonyOS SDK助力新浪新闻打造精致易用的资讯服务新体验

    原生智能是HarmonyOS NEXT的核心亮点之一,依托HarmonyOS SDK丰富全面的开放能力,开发者只需通过几行代码,即可快速实现AI功能.新浪新闻作为鸿蒙原生应用开发的先行者之一,从有声资 ...

  2. 国内十大活跃报表 BI 产品深度点评

    目前国内市场上的报表 BI 工具琳琅满目,看起来也各有特点,这给选型工作带来了一些困扰,本文就一些较活跃的报表 BI 产品进行点评,对于不太熟悉这些产品和技术的同学,可作为参考资料. 这里选了十个产品 ...

  3. redis 简单整理——bitmaps[十二]

    前言 简单介绍一下bitmaps这个东西. 正文 我们都知道bitmaps 翻译过来就是二进制. 那么二进制可以存一些什么呢? 图片.视频,还可也存些什么呢? 现代计算机用二进制(位)作为信息的基础单 ...

  4. 重新点亮linux 命令树————rpm软件包管理[十一七]

    前言 简单介绍一下软件管理 正文 软件包管理器 rpm 包和rpm 命令 yum 仓库 源代码编译安装 内核升级 grub配置文件 软件包管理器: 包管理器是为了方便软件安装.卸载,解决软件依赖关系的 ...

  5. linux ssh连接

    前言 整理以前的随笔. 正文 首先更新源 sudo apt-get update 安装ssh服务 sudo apt-get install openssh-server 检测是否已启动 ps -e | ...

  6. shell编程实现用户循环输入

    如果你想在Shell脚本中实现一个循环判断用户输入是否正确,并根据情况决定是否退出系统,可以使用一个无限循环(如while true)和条件语句来实现. 以下是一个示例代码,用于演示这种情况: #!/ ...

  7. 初接触:从创建工程到导出gerber(学习Altium Designer)

    学习Altium Designer Altium Designer的工程文件后缀为.PrjPcb,主要包含Source Documents和Libraries.Source Documents里面有S ...

  8. 第九課-Channel Study For Caller Client Api

    1.浏览Mirth Connect开放Client API 2.启动Vs2019,编程测试Client Api的调用 开启你在宇宙第一IDE下熟悉的.net之旅吧!

  9. 重新定义容器化 Serverless 应用的数据访问

    简介: 本文首先聚焦到 AI 和大数据等应用 Serverless 化的最大挑战:计算和存储分离架构带来的数据访问延迟和远程拉取数据带宽巨大的挑战.尤其在 GPU 深度学习训练场景中,迭代式的远程读取 ...

  10. KubeVela 1.3 发布:开箱即用的可视化应用交付平台,引入插件生态、权限认证、版本化等企业级新特性

    ​简介:得益于 KubeVela 社区上百位开发者的参与和 30 多位核心贡献者的 500 多次代码提交, KubeVela 1.3 版本正式发布.相较于三个月前发布的 v1.2 版本[1],新版本在 ...