黄色的线是天正建筑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. Python scipy.ndimage.find_objects用法及代码示例

    用法 scipy.ndimage.find_objects(input, max_label=0) 在标记数组中查找对象. 参数: input: 整数数组 包含由不同标签定义的对象的数组.值为 0 的 ...

  2. 开发案例:使用canvas实现图表系列之折线图

      一.功能结构 实现一个公共组件的时候,首先分析一下大概的实现结构以及开发思路,方便我们少走弯路,也可以使组件更加容易拓展,维护性更强.然后我会把功能逐个拆开来讲,这样大家才能学习到更详细的内容.下 ...

  3. Vim 安装与基础操作指南

    0x00 链接 Vim 官网 Vim GitHub Vim 中文文档 0x01 准备 (1)下载与安装 在官网地址找到 Download 标签,在其中根据操作系统选择相应的版本,以下以 Windows ...

  4. 响应式系统与 React

    0x1 React 的历史与应用 应用场景 前端应用开发,如 Meta.Ins.Netflix 的网页版 移动原生应用开发,如 Ins.Discord 结合 Electron 进行桌面应用开发 发展历 ...

  5. 在centOS上配置web服务器

    centos,web服务,apache,ftp服务器,mysql,makefile (1). 检查系统是否正常 # more /var/log/messages //检查有无系统内核级错误信息 # d ...

  6. identity4 系列————用户数据持久化篇[六]

    前言 前面的例子已经将各种情形下的例子已经介绍了一遍,那么后面就是用户数据持久化该如何处理了. 正文 例子位置: https://github.com/IdentityServer/IdentityS ...

  7. SSM使用自定义ConditionalOnProperty实现按需加载spring bean

    SSM使用自定义ConditionalOnProperty实现按需加载spring bean 背景: 公司提供的系统框架是SSM架构,SSM架构是没有springboot的ConditionalOnP ...

  8. kolla-ansible部署OpenStack Train版技术方案

    简单架构示意 项目目标 1. 实现容器化部署docker+ Ansible+openstack-tarin 2. 使用keeplived监控nova服务实现在单台服务器宕机的情况下能迅速切断连接减轻平 ...

  9. asyncio和aiohttp携程并发

    import asyncio from aiohttp import web import time async def process(): for i in range(10): print(&q ...

  10. 力扣303(java)-区域和检索-数组不可变(简单)

    题目: 给定一个整数数组  nums,处理以下类型的多个查询: 计算索引 left 和 right (包含 left 和 right)之间的 nums 元素的 和 ,其中 left <= rig ...