【已更新】待会想说一个今天遇到的关于数组和线段的程序员逻辑

先占个坑

=======================================================================================

2016/10/26 16:40更新


最近还是在做在线标定的功能,先前做的功能是能够在网页上对一副(OCT)图像进行标定,更通俗的说,就是在OCT图像上让专家用笔画线,用线分割出每一层。

说下我的实现,首先整体是在canvas上作图,设备是电容屏,所以需要调用onTouch系列的接口。我在onTouchMove中每move一下,就从前一个记录的点到当前位置画一条线段,把这条线段画出来。

function onTouchMove(event) {
    event.preventDefault();
    //单点
    var pos = windowToCanvas(canvas, event.touches[0].clientX, event.touches[0].clientY);
    drawLine(lastX,lastY,pos.x,pos.y);
   	
    lastX=pos.x;
    lastY=pos.y;
   
}

最后将这些线段存到数据库。

这里把线段按照作图先后顺序存到一个数组里。

以上是背景。


现在提出了一个新功能,由于屏幕作图有误差,这次画一条线中间停了,下次又要开始从这离开时画,下笔时会留出空隙,为了解决这个问题,需要弄一个填补缝隙的功能。简而言之,对于隔着很近的两条线段,能够自动练成一条线段。

对于这个需求,最初给出的解决方案是弄一个检测曲线端点的函数,然后对于在范围内的端点找出距离最小的,连上。如背景所介绍,一条曲线是由多个线段组成,由于画的先后顺序,决定了每个线段在数组中存的顺序,只要线段连续,那么在数组中的存的位置应该是连续的。但是后来想了一下,由于我加了连线的功能,会导致后连进去的线其实也算是同一个曲线上,而且我还加了橡皮擦的功能,可以擦断曲线,所以同一条曲线的线段在数组中存的位置连续并不成立。

思路一:

然后我想了一个O(N^2)的暴力方法,从一个线段开始找和它相连的令一个线段,这样拼出一整条曲线,然后找下一条曲线,暴力的找出每条曲线是由哪些线段构成。复杂度是怎么算的呢,为什么不是O(N^3)而是O(N^2)?每条线段能在O(N)的复杂度内从数组中找到和它相连的另一条线段,由N条线段,所以复杂度是O(N^2)。最后找出这些端点,在O(N)的复杂度下和已知点判断一下距离。

然后我觉得这样的实现方法在前端js的运行效率不说,我觉得不够优雅,想了一个O(NlogN)的,而且思路很简单。

思路二如下:

在触屏环境下,我认为手动触屏产生不了两个完全一样的浮点数,比如你摸一个位置两次,上一次坐标是(1.5,2.5),下一次也许就是(1.499999,2.5000000001),世界不会有随机巧合到两个浮点数同时一样,连后面的很小的位数都一样。我先判断每个线段的端点距离已知点的距离,在O(N)的复杂度中筛选出符合距离限制的端点。然后如果两条线段连续,那么必然有端点的坐标是完全一样的(连小数后面的每一位都一模一样)。所以对这些端点进行排序O(NlogN),如果端点有重复就把这个值的所有端点都删掉,因为必然不是曲线的端点,所以剩下的不重复的都是曲线的端点。从这些端点中找到最近的那个就OK。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值