cad.net bo边界算法

您所在的位置:网站首页 cad边界的作用 cad.net bo边界算法

cad.net bo边界算法

2023-08-12 21:59| 来源: 网络整理| 查看: 265

发送lisp

(bpoly point)

发送命令

Acad的低版本只能发送命令的方式获取边界信息,edata说这个bo是写在arx内的,不是接口,所以也不能反射用(没深究了)

低版本: 通过命令发送bo的方法:发送bo命令例子

要注意的是,如果空格再次执行上次命令,你会执行到bo,而不是你的当前命令. 而正常的cad用户都是要执行当前的命令. 例如填充命令发送bo命令,那么再次空格是bo,而用户需要是填充

解决方法:要解开文档锁的情况下发送一次当前命令,而且在命令函数外做一个立即结束的标记, 在最前面写: img

到了Acad2011: 就可以通过以下语句获取

Editor ed = Acap.DocumentManager.MdiActiveDocument.Editor; ed.TraceBoundary(........); 算法概念

但是,要是自己能造一个边界算法,为什么要靠桌子的.

打倒自动桌子!!!! 打倒Acad!!!

img

分析桌子的bo算法

桌子的bo算法原理: 先获取当前屏幕可视的图形,然后用的是像素一点一点抓边界像素(填充法),所以非常快.

知道了之后,就明白这是一个前台操作,而我们需要挑战的是后台bo算法,也就是无像素的前提下分析边界. 而且必须要做得很快,不然就没有意义啦.

方案一,单点射线法(实际上就是夹角左转法)

于是乎,我做了一张图(拖拉图片看大图)

不要问为什么是奇点不是起点,因为起点的意义太多了,换个字免得引起歧义而已(用原点又会跟世界坐标原点重意辣!像爆炸一样辐射获取收到冲击波的边界).

img

1, 减少遍历,不可能O(n²)比较的,所以我们利用四叉树 制作一个查找临近图元的功能,这个比较简单,我都写完了.

2, 抛弃非边界计算图元,例如文字,标注,引线. 如果奇点,不在块的嵌套层次上,那么表示块边界才是遍历的,(此边界相当于bv树的外层) 如果在嵌套层次里,先算层次内,边界没密封才继续遍历其他块边界.

下面是山人告诉我的bo算法思想... 它就是图上的拆解算法.

样图

img

全部交点打断,然后bo到的边界就是我标数字的线段组成的.(其实不是打断,是求交点,我是便于大家理解)

步骤如下 0x01 射线求交点

img

从A点做0°直线(射线),与所有的线只有4个交点,就是我画绿色圆的点;

选择一个离A点最近的点,并通过这个点得到1号直线: 数学上来讲就是两个直线方程联立.

0x02 获取下一段线段

img

得到1号直线的两个端点,选择相对A-1线角度逆时针方向的点C,

由C点做选择集,得到2号和1号直线,排除1号直线: 可能C点相交有多个图元,存在和 0x03 一样的情况,可能存在没有相交的图元,需要细节处理.

然后用2号直线的另一个交点d做选择集: 非选择集需要轮询(所有图元? 2号线包围盒范围内的?) 与2号线来求交,得出最近交点,

得到2号、3号,21、22号直线.(如果是不打断的话,则没有21、22,但是,万一情况是图元接上去呢,则需要以相同条件来进行)

0x03 逆时针选择的作用

这个时候,你要选择3号直线才是对的,

算法应选择直线的角度更靠近逆时针的那个: 也就是说d为基点,22号 在最右,21在中间,3在最左,那就选择最左的那个3

这时候的你轮廓集合里已经有3条直线了,分别为1 、2 、 3

0x04 循环以上操作

然后就是不断的重复,直到走到12号线,又一次选择到了1号线,循环结束;

分析

经过0x01和0x02的步骤可知,每次都需要轮询一次所有的图元,那么这个轮询就是数量就是线性递减的,因为已经分析过的图元,除了第一个需要保留以判断闭环之外,其他都可以抛弃.

这个是最简单的,没有内部孤岛,没有曲线,的bo原理.

方案二

我们发现上面的算法它在计算单一闭合好用,但是多闭合就有问题.

于是乎找到了此论文,主要是利用图来实现. 图分为邻接表和邻接矩阵. 当模型比较小的时候,用矩阵有优化效率.原因是邻接表是内存离散模型,矩阵是连续的(内存不存在多维数组,全是一维模拟的),而我们需要高频访问矩阵,这是优化阶段的东西. 二维图形封闭区域自动识别算法

广度优先算法

根据论文,使用了一个邻接表,c#直接用词典模拟了它, 邻接表的key是交点字符串(注意要去精度), value是节点类,类中有相遇链/坐标/颜色/步数(论文是长度,更具体见论文), 当分类完成之后,1{2,9}表示1节点同时链接着2,9节点.

论文核心是染色过程中提取了相遇链,核心是相遇时候的处理,然后回溯父节点. 其中染色的O(n)一次完成.

但是阿惊依照论文流程实现了一次代码之后,发现有蛮多点和我们想要的曲线闭合不太相同. 不好的地方是相遇点再次寻找到下一个相遇点时候, 第2,3,4...节点不能父节点回溯,而是图会呈现水波状态向外绽放, 所以论文只会呈现最后图样那样,也就是一次回溯.

也跟bo算法中直接提取所有封闭区不同...难搞噢,或许你们可以想到一个顺利回溯水波状方法的方法.😆

山人找到了这个stackoverflow:find-all-chordless-cycles

不过要注意:图的算法是抛弃双曲线闭合(单曲线闭合直接过滤图元属性就好了),这样的ab两个节点就包含一个闭合区.这也难搞噢.

此处待续...

深度优先算法

小学问题:数数里面多少个多边形...成人解决方案版. 实际上我们只需要1/2/3区. 邻接表进行深度优先是利用穷举每个节点而成立的,闭环一个,回上一个分叉路再寻.

涂色在这里可以变成: 我们遍历每个节点必然会有8字型走成b或者p,腰身闭合的情况. 那么我们每走一步就遍历一次全部腰身的话,很蛋疼,所以设计了这个涂色. 涂色也可以是个序号,例如碰到4号,尾巴到4就是一条闭合线了. 每次完成一次遍历需要把涂色全部归0.

但是我觉得这样会造成一个可怕的结果, 穷举的多段线点序是下移的,也就是:点123/231/312,然后还有双向:点321/213/132, 并且还会穷举出一些我们不要的(图上面的4/5/6区) 一条多段线就那么多了耶.这要很多个数组储存呀.判断重复也需要处理时间.

总结起来就是: key序号就失去了角度性,得到了快捷,快捷又出现了穷举,穷举又带来了点序下移和双向和废区.

方案三

通过有限采样进行获取三角封闭区,这个方法没有进行过实践, 而且这样貌似和三维建模如出一辙.

(完)



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3