1. 点线面数据格式
- 点:
{ x: xxx, y: xxx }
- 线:
[{ x: xxx, y: xxx }, { x: xxx, y: xxx }]
- 面:
[{ x: xxx, y: xxx }, { x: xxx, y: xxx }, { x: xxx, y: xxx }...]
2. 重叠情况分析:无外乎相交与包含两种情况
(1 判断相交
//判断两多边形线段是否相交
function isSegmentsIntersectant(segA, segB) {//线线
const abc = (segA[0].x - segB[0].x) * (segA[1].y - segB[0].y) - (segA[0].y - segB[0].y) * (segA[1].x - segB[0].x);
const abd = (segA[0].x - segB[1].x) * (segA[1].y - segB[1].y) - (segA[0].y - segB[1].y) * (segA[1].x - segB[1].x);
if (abc * abd >= 0) {
return false;
}
const cda = (segB[0].x - segA[0].x) * (segB[1].y - segA[0].y) - (segB[0].y - segA[0].y) * (segB[1].x - segA[0].x);
const cdb = cda + abc - abd;
return !(cda * cdb >= 0);
}
//判断两多边形边界是否相交
function isPolygonsIntersectant(plyA, plyB) {//面面
for (let i = 0, il = plyA.length; i < il; i++) {
for (let j = 0, jl = plyB.length; j < jl; j++) {
const segA = [plyA[i], plyA[i === il - 1 ? 0 : i + 1]];
const segB = [plyB[j], plyB[j === jl - 1 ? 0 : j + 1]];
if (isSegmentsIntersectant(segA, segB)) {
return true;
}
}
}
return false;
}
(2 判断包含
function isPointInPolygon(point, polygon) {
var N = polygon.length;
var boundOrVertex = true;
var intersectCount = 0;
var precision = 2e-10;
var p1, p2;
var p = point;
p1 = polygon[0];
for (var i = 1; i <= N; ++i) {
if (p.x == p1.x && p.y == p1.y) {
return boundOrVertex;
}
p2 = polygon[i % N];
if (p.y < Math.min(p1.y, p2.y) || p.y > Math.max(p1.y, p2.y)) {
p1 = p2;
continue;
}
if (p.y > Math.min(p1.y, p2.y) && p.y < Math.max(p1.y, p2.y)) {
if (p.x <= Math.max(p1.x, p2.x)) {
if (p1.y == p2.y && p.x >= Math.min(p1.x, p2.x)) {
return boundOrVertex;
}
if (p1.x == p2.x) {
if (p1.x == p.x) {
return boundOrVertex;
} else {
++intersectCount;
}
} else {
var xinters = (p.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x;
if (Math.abs(p.x - xinters) < precision) {
return boundOrVertex;
}
if (p.x < xinters) {
++intersectCount;
}
}
}
} else {
if (p.y == p2.y && p.x <= p2.x) {
var p3 = polygon[(i + 1) % N];
if (p.y >= Math.min(p1.y, p3.y) && p.y <= Math.max(p1.y, p3.y)) {
++intersectCount;
} else {
intersectCount += 2;
}
}
}
p1 = p2;
}
if (intersectCount % 2 == 0) {
return false;
} else {
return true;
}
}
function isPointInPolygonBidirectional(plyA, plyB) {
let [a, b] = [false, false];
a = plyA.some(item => isPointInPolygon(item, plyB));
if (!a) {
b = plyB.some(item => isPointInPolygon(item, plyA));
}
return a || b;
}
3. 判断多边形是否重叠
function isPolygonsOverlap(plyA, plyB) {
return isPolygonsIntersectant(plyA, plyB) || isPointInPolygonBidirectional(plyA, plyB);
}