vue.js 实现凸包算法
需求描述:
在地图中,选中若干个点,需求要求用阴影盖住所有的点(点也可以理解成地点、设备、建筑物等),已知所有的点的坐标,求一个最大不规则多边形,即求出围成这个多边形的点。
用到两个算法
handlePoints(lines) {
//排序去重
for (let i = 0; i < lines.length; i++) {
for (let j = 0; j < lines.length - i - 1; j++) {
if (lines[j][0] > lines[j + 1][0]) {
let tamp = lines[j];
lines[j] = lines[j + 1];
lines[j + 1] = tamp;
}
if (lines[j][0] == lines[j + 1][0] && lines[j][1] == lines[j + 1][1]) {
lines.splice(j + 1, 1);
j--;
}
}
}
let result = [];
let index = 1;
result.push(lines[0]);
while (true) {
let point = this.findNext(lines, result[index - 2], result[index - 1]);
if (point == null) break;
result.push(point);
if (point[0] == lines[0][0] && point[1] == lines[0][1]) {
break;
}
if (index > lines.length + 2) {
break;
}
index++;
}
return result;
},
findNext(lines, start, node) {
for (let i = 0; i < lines.length; i++) {
if (start != null && start[0] == lines[i][0] && start[1] == lines[i][1]) {
continue;
}
if (node != null && node[0] == lines[i][0] && node[1] == lines[i][1]) {
continue;
}
let search = true;
let target = -9999;
for (let j = 0; j < lines.length; j++) {
if (i == j) continue;
if (node != null && node[0] == lines[j][0] && node[1] == lines[j][1]) {
continue;
}
let left =
this.sub(node[0], lines[j][0]) * this.sub(lines[i][1], lines[j][1]) -
this.sub(node[1], lines[j][1]) * this.sub(lines[i][0], lines[j][0]) >
0
? true
: false;
if (target == -9999) {
target = left;
}
if (left != target) {
search = false;
break;
}
}
if (search == true) {
return lines[i];
}
}
},
mul(a, b) {
var c = 0,
d = a.toString(),
e = b.toString();
try {
c += d.split(".")[1].length;
} catch (f) { }
try {
c += e.split(".")[1].length;
} catch (f) { }
return (
(Number(d.replace(".", "")) * Number(e.replace(".", ""))) / Math.pow(10, c)
);
},
sub(a, b) {
var c, d, e;
try {
c = a.toString().split(".")[1].length;
} catch (f) {
c = 0;
}
try {
d = b.toString().split(".")[1].length;
} catch (f) {
d = 0;
}
return (e = Math.pow(10, Math.max(c, d))), (this.mul(a, e) - this.mul(b, e)) / e;
}