<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>

    <script>

        // 点: [x,y]
        // 线: [[x,y],[x,y]]
        // 面: [[x,y],[x,y],[x,y]...]

        // 1 判断相交
        //判断两多边形线段是否相交
        function isSegmentsIntersectant(segA, segB) {//线线
            const abc = (segA[0][0] - segB[0][0]) * (segA[1][1] - segB[0][1]) - (segA[0][1] - segB[0][1]) * (segA[1][0] - segB[0][0]);
            const abd = (segA[0][0] - segB[1][0]) * (segA[1][1] - segB[1][1]) - (segA[0][1] - segB[1][1]) * (segA[1][0] - segB[1][0]);
            if (abc * abd >= 0) {
                return false;
            }
            const cda = (segB[0][0] - segA[0][0]) * (segB[1][1] - segA[0][1]) - (segB[0][1] - segA[0][1]) * (segB[1][0] - segA[0][0]);
            const cdb = cda + abc - abd;
            console.log("线段是否相交:", !(cda * cdb >= 0));
            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)) {
                        console.log("边界相交:");
                        return true;
                    }
                }
            }
            console.log("边界不相交:");
            return false;
        }
    

        // 2 判断包含
        //判断点是否在另一平面图中
       
       function pointInPolygon(point, vs) {

            // https://github.com/substack/point-in-polygon

            const x = point[0], y = point[1];

            let inside = false;
            for (let i = 0, j = vs.length - 1; i < vs.length; j = i++) {
                const xi = vs[i][0], yi = vs[i][1];
                const xj = vs[j][0], yj = vs[j][1];

                const intersect = ((yi > y) !== (yj > y))
                    && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
                if (intersect) {
                    inside = !inside;
                }
            }
            console.log(inside);
            return inside;
        }

        //判断两多变形是否存在点与区域的包含关系(A的点在B的区域内或B的点在A的区域内)
        function isPointInPolygonBidirectional(plyA, plyB) {//面面
            let [a, b] = [false, false];
            a = plyA.some(item => pointInPolygon(item, plyB));
            if (!a) {
                b = plyB.some(item => pointInPolygon(item, plyA));
            }
            console.log("包含关系:", a || b);
            return a || b;
        }

        // 3 判断多边形是否重合
        function isPolygonsOverlap(plyA, plyB) {
            return isPolygonsIntersectant(plyA, plyB) || isPointInPolygonBidirectional(plyA, plyB);
        }

        // const plyA = [[109.12560386473433, 333.99033816425117],[367.90096618357484, 333.99033816425117],[239.1570048309178, 462.7342995169082]],
        // plyB = [[122.78502415458934, 261.3623188405797],[187.1570048309178, 325.7342995169082],[122.78502415458934, 390.10628019323667]];
        const plyA = [[121, 196], [185, 261], [185, 390], [121, 325]],
            plyB = [[138, 363], [202, 299], [266, 363]]

            ;

        const isOver = isPolygonsOverlap(plyA, plyB);
        console.log(isOver)

    </script>
</body>

</html>

纤细的一帆风顺
40 声望2 粉丝