小伙伴你们设计网络的时候有没有遇见过下面的一些问题: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);
复制代码
以上就是今天给大家带来的。