发送命令
Acad的低版本只能发送命令的方式获取边界信息,edata说这个bo是写在arx内的,不是接口,所以也不能反射用(没深究了)
到了Acad2011,就可以通过以下语句获取:
Editor ed = Acap.DocumentManager.MdiActiveDocument.Editor;
ed.TraceBoundary(........);
然后低版本,通过命令发送bo的方法:点我
要注意的是,如果空格再次执行上次命令,你会执行到bo,而不是你的当前命令..而正常的cad用户都是要执行当前的命令.
解决方法:要解开文档锁的情况下发送一次当前命令,而且在命令外做一个立即结束的标记,在最前面写:
算法概念
但是,要是自己能造一个边界算法,为什么要靠桌子的.
打倒自动桌子!!!! 打倒Acad!!!
于是乎,我做了一张图(拖拉图片看大图)
不要问为什么是奇点不是起点,因为点的意义太多了,换个字免得引起歧义而已(用原点又会跟世界坐标原点重意辣!).
分析桌子算法
本来的初衷是觉得它的边界算法无法很好的将边界线给闭合,所以是想通过遍历数据库来实现对屏幕外的边界做补充.
在了解了桌子的bo算法原理之后,决定放弃...因为它的是最佳实践来的,几乎没什么好改的.
其先获取当前屏幕可视的图形,然后遍历它们的图元信息,而按照我的想法,将不可避免的很多次数据库.
但是要自己干也不是不可能,尤其是可以做优化算法:
1, 获取屏幕内图元时候加一条屏幕边界来做范围.
利用四叉树
2, 需要减少双层遍历数量O(n²)复杂度:
抛弃非边界计算图元,例如文字,标注,引线.
如果奇点,不在块的嵌套层次上,那么表示块边界才是遍历的,(此边界是指块内涉及边界的图元,并且造成一条链)
如果在嵌套层次里,先算层次内,边界没密封才继续遍历其他块边界.
拆解算法
下面是山人告诉我的bo算法思想... 它就是图上的拆解算法.
样图
全部交点打断,然后bo到的边界就是我标数字的线段组成的.(其实不是打断,是求交点,我是便于大家理解)
步骤如下
&1 射线求交点
从A点做0°直线(射线),与所有的线只有4个交点,就是我画绿色圆的点;
选择一个离A点最近的点,并通过这个点得到1号直线: 数学上来讲就是两个直线方程联立.
&2 获取下一段线段
得到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原理.
(完)