cad.net bo边界算法


发送命令

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

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

Editor ed = Acap.DocumentManager.MdiActiveDocument.Editor;
ed.TraceBoundary(........);

然后低版本,通过命令发送bo的方法:点我

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

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

img

算法概念

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

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

img

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

不要问为什么是奇点不是起点,因为点的意义太多了,换个字免得引起歧义而已(用原点又会跟世界坐标原点重意辣!).

img

分析桌子算法

本来的初衷是觉得它的边界算法无法很好的将边界线给闭合,所以是想通过遍历数据库来实现对屏幕外的边界做补充.

在了解了桌子的bo算法原理之后,决定放弃...因为它的是最佳实践来的,几乎没什么好改的.

其先获取当前屏幕可视的图形,然后遍历它们的图元信息,而按照我的想法,将不可避免的很多次数据库.

但是要自己干也不是不可能,尤其是可以做优化算法:

1, 获取屏幕内图元时候加一条屏幕边界来做范围.
利用四叉树

2, 需要减少双层遍历数量O(n²)复杂度:
抛弃非边界计算图元,例如文字,标注,引线.
如果奇点,不在块的嵌套层次上,那么表示块边界才是遍历的,(此边界是指块内涉及边界的图元,并且造成一条链)
如果在嵌套层次里,先算层次内,边界没密封才继续遍历其他块边界.

拆解算法

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

样图

img

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

步骤如下

&1 射线求交点

img

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

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

&2 获取下一段线段

img

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

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

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

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

&3 逆时针选择的作用

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

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

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

&4 循环以上操作

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

分析

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

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

(完)


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM