最近写了个小demo,含金量很高,感谢南先生;
demo需求是这样的:浏览器里加载到cad图像并且已经用threejs 渲染出来,所有线段数据已存放于内存,那么我要做的就是双击图形中的任意一个闭合区间,返回围成这个闭合区间的点。demo的实现思路网上已有,难就难在效率,线段很多,运算量很大,想要在客户点击第一时间返回面积数据,还是比较难的,尤其是用js实现,弄不好搞崩溃浏览器。
实现思路:
1、将所有的线段两两相交计算出所有交点
2、用交点打断所有线段,形成新的线段集合
3、去掉孤立的线段,保证图形中都是闭合区间,以减少将来不必要运算(对比之后的优化,此步骤已无足轻重)
4、封装点到线 与 线到点的关系,保证从任意一点能找到这点连接的线段,任意一个线段能找到线段两端的点,以便后续寻找鼠标点击位置所在闭合区间
5、由闭合区间内鼠标点击的坐标点 发射一条射线,射线与图形相交的点按从小到大排序,最小的那点可能是鼠标点击所在的闭合区间(也可能不是,存在闭合区间内有其他闭合区间的情况)
6、由上一步的最小交点出发,根据第四步的关系寻找所有闭合区间,找到所有闭合区间后,筛选出鼠标点击所在的最小区域,就是我们要的结果了。
以上已实现客户需求,代码写至此,测试发现速度慢的令人崩溃,经南先生分析指导,有了以下优化方案,可谓神来之笔
优化方案:
1、优化上面第2步:因为取线段交点时不知道谁和谁相交,只能遍历所有线段和剩余所有线段相交取交点,实际上大部分的循环是无效的,因为一个线段一般也就和两三个线段相交,但是我却要几乎和全部线段都比较一遍。采用16叉树,将图形逻辑分成16个区域,每区域内的线段自己比较,跨区域线段与所跨区域比较,优化有发现速度快了一倍,但和理想的距离还很遥远
2、优化上面第6步:从众多的线段中寻找那个最优路径,采用向量右手法则,每个点往下走的话,都按照右手定则排个序。如果不知道右手定则是啥的话,补补向量和初中的三角函数和象限,都是基础知识。“奇变偶不变符号看象限”。
以上优化后,大多数图形的反应速度都控制在了3秒内,那超过三秒的是什么情况呢?就是第2步,线太多还是慢,后来这个也给优化掉了,就是用的js多线程,一加载图就用多线程开始寻找线段交点,可能你看了会儿图,要点击的时候,交点早已生成好了。
thats all
就这么漂来漂去的