网络设计中闭合线条和非闭合线条的实现

小伙伴你们设计网络的时候有没有遇见过下面的一些问题:1.在一堆的线段或者折线段内找出闭合折线段或者闭合边框。2.把端点相连(相距安全距离之内)的多个线段合成一条折线段。3.合成后的线段基础上闭合边框和非闭合边框进行分类。4.收集它们的坐标信息加以利用。如果有,就好好看下面给大家分享的这片文章。

复制代码

/*

* 【寻找闭合边框】by 秋叶博客 http://www.mizuiren.com/497.html

* linesPoints可以是线条坐标点集[[{x:1,y:2},{x:2,y:3}],[{x:4,y:2},{x:6,y:7},{x:4,y:2}]]

* linesPoints也可以是线条的dom对象集合[document.querySelectorAll('polyline/line')];

* tolerance:安全间距

* */

function findCloseLine(linesPoints, tolerance) {

   var pointArrs = linesPoints;

   tolerance = tolerance || 0;//间隔,两个点相距多远以内算可以连接

   if (!Array.isArray(linesPoints[0])) {//如果数组元素不是个对象就按照dom对象来处理

      pointArrs = [];

      if(!Array.isArray(linesPoints )) {//如果是个dom集合,要把它转成数组

         linesPoints = [].slice.call(linesPoints);

      }

      if (!tolerance) {

         tolerance = linesPoints[0].getAttribute('stroke-width');//间隔取第一条线条的宽度

      }

      var points, match, xy, xys;

      linesPoints.forEach(function (line) {//把它们的路径转成坐标对象

         points = line.getAttribute('points') || line.getAttribute('d');

         if (!points) {

            return;

         }

         match = points.match(/\-?\d+(\.\d+)?.*?\d+(\.\d+)?/g);

         xys = [];

         match.forEach(function (item) {

            xy = item.match(/(\-?\d+(\.\d+)?).*?(\-?\d+(\.\d+)?)/);

            xys.push({

               x: +xy[1],

               y: +xy[3]

            });

         });

         pointArrs.push(xys);

      });

   }

   var closed = [], hadSearchIndexs = [], notClosed = [], combinePoint = [], hadCombinePoint;

   pointArrs.forEach(function (_points, index) {

      if (getDistance(_points[0], _points[_points.length - 1]) <= tolerance) {

         closed.push(_points);

         hadSearchIndexs.push(index);

         return;

      }

      combinePoint = [];

      hadCombinePoint = findNextConect(index, _points[0], 'begin');//查找线头的连接点

      if (!hadCombinePoint) {

         hadCombinePoint = findNextConect(index, _points[_points.length - 1], 'end');//查找线尾的连接点

      }

      if (hadCombinePoint) {//如果找到了连接点

         if (getDistance(hadCombinePoint[0], hadCombinePoint[hadCombinePoint.length - 1]) <= tolerance) {

            closed.push(hadCombinePoint);

         } else {

            notClosed.push(hadCombinePoint);

         }

      } else {//如果没有找到了连接点

         hadCombinePoint === '' || notClosed.push(_points);//hadCombinePoint为‘’(就是已经被连接了或当前线段)的时候不算在非闭合集合里面

      }

      hadSearchIndexs.push(index);

   });

 

   //拿一个端点去与其它线段的端点算距离判断是否相连,若相连把它们的坐标合并在一起组成一个完整线条

   function findNextConect(currentIndex, point, beginOrEnd) {

      var hadConected, connectPoint, currentLine, _thisLinePoints;

      var combinePoint = [];

      _infun(currentIndex, point, beginOrEnd);

 

      function connectAction(beginOrEnd1, beginOrEnd2, waitConnectLine, index) {

         if (beginOrEnd1 === beginOrEnd2) {

            _thisLinePoints = _thisLinePoints.reverse();

         }

         _action(beginOrEnd1, waitConnectLine);

         hadConected = true;

         hadSearchIndexs.push(index);

         _infun(currentIndex, connectPoint, beginOrEnd1);

 

         function isRepeatPoint(begin, end) {

            var endLastIndex = end.length - 1;

            return end[endLastIndex].x === begin[0].x && end[endLastIndex].y === begin[0].y;

         }

 

         function _action(beginOrEnd, waitConnectLine) {

            if (beginOrEnd === 'begin') {

               if (isRepeatPoint(waitConnectLine, _thisLinePoints)) {

                  _thisLinePoints.pop();

               }

               combinePoint = _thisLinePoints.concat(waitConnectLine);

               pointArrs[currentIndex] = combinePoint;

               connectPoint = combinePoint[0];

            } else {

               if (isRepeatPoint(_thisLinePoints, waitConnectLine)) {

                  _thisLinePoints.shift();

               }

               combinePoint = waitConnectLine.concat(_thisLinePoints);

               pointArrs[currentIndex] = combinePoint;

               connectPoint = combinePoint[combinePoint.length - 1];

            }

         }

 

      }

 

      function _infun(currentIndex, point, beginOrEnd) {

         var waitConnectLine = pointArrs[currentIndex];

         if (waitConnectLine) {

            for (var i = 0; i < pointArrs.length; i++) {

               _thisLinePoints = JSON.parse(JSON.stringify(pointArrs[i]));//克隆对象,因为后面需要删改它

               if (i === currentIndex) {

                  continue;

               }

               if (hadSearchIndexs.indexOf(currentIndex) > -1) {

                  currentLine = '';

                  continue;

               }

               if (hadSearchIndexs.indexOf(i) > -1) {

                  continue;

               }

               if (getDistance(_thisLinePoints[0], point) <= tolerance) {

                  connectAction(beginOrEnd, 'begin', waitConnectLine, i);

                  break;

               } else if (getDistance(_thisLinePoints[_thisLinePoints.length - 1], point) <= tolerance) {

                  connectAction(beginOrEnd, 'end', waitConnectLine, i);

                  break;

               }

            }

         }

      }

 

      if (combinePoint.length) {

         return combinePoint;

      } else {

         return currentLine;

      }

   }

 

   //计算两个点的距离

   function getDistance(p1, p2) {

      return Math.sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));

   }

 

   var category = {//返回闭合边框和非闭合边框的分类坐标点集合

      closed: closed,

      notClosed: notClosed

   }

   return category;

}

//调用:

findCloseLine([document.querySelectorAll('polyline')], 10);

复制代码

以上就是今天给大家带来的。

 

猜你喜欢

转载自blog.csdn.net/weixin_43955838/article/details/86714224
今日推荐