如何使用 Javascript 检测路径之间的交叉点

How do I use Javascript to detect intersections between paths

我在这个嵌套数组中有以下坐标,它们为每个玩家生成一条路径。它们都是直角的直线。现在的问题是,我没有任何方法可以让我计算每条路径之间任何潜在交叉点的坐标,以防它们重叠。

有谁知道 Javascript 方法允许我计算动态数量的路径之间的任何交点,每个路径具有不同数量的坐标集?

这是它在前端的样子,只是为了给你一张图片:

How it looks in the frontend

这是我用来在 HTML canvas 上生成路径的数组代码:

var data = [{
    "uid": 1,
    "prop": [{
        "name": "im1tta",
        "color": "#5FFFC1",
        "path": [{
            "x": 20,
            "y": 20
        }, {
            "x": 20,
            "y": 100
        }, {
            "x": 70,
            "y": 100
        }, {
            "x": 70,
            "y": 200
        }]
    }]
}, {
    "uid": 2,
    "prop": [{
        "name": "Difan",
        "color": "#FF5F88",
        "path": [{
            "x": 450,
            "y": 100
        }, {
            "x": 450,
            "y": 210
        }, {
            "x": 400,
            "y": 210
        }]
    }]
}, {
    "uid": 3,
    "prop": [{
        "name": "Alina",
        "color": "#5F78FF",
        "path": [{
            "x": 310,
            "y": 200
        }, {
            "x": 350,
            "y": 200
        }, {
            "x": 350,
            "y": 290
        }, {
            "x": 410,
            "y": 290
        }, {
            "x": 410,
            "y": 320
        }]
    }]
}];

顺便说一句,这是我的第一个 Whosebug 问题,感谢您帮助我!

我已经解决了这个问题,我花了一段时间才理解这个概念,但我的情况很简单,因为这些线都是直角的。

这是我的解决方案,它可能不是最好的解决方案,但它工作得很好,即使在高频循环中也是如此:

function checkPlayerCollision(a1, b1, a2, b2) {
    var state1 = checkForDirection(a1, b1);
    var state2 = checkForDirection(a2, b2);

    var collisionX = null,
        collisionY = null;

    if (state1 !== state2) {
        if (state1 === "horizontal") {
            collisionX = horizontal(a1, b1, a2, b2);
            collisionY = vertical(a1, b1, a2, b2);
        } else {
            collisionX = horizontal(a2, b2, a1, b1);
            collisionY = vertical(a2, b2, a1, b1);
        }
    } else if (state1 === state2) {
        if (state1 === "horizontal") {
            if (a1.y === a2.y) {
                collisionY = a1.y;
                if (a1.x < b1.x) {
                    if (a2.x <= b1.x && a2.x >= a1.x) {
                        collisionX = a2.x;
                    } else if (b2.x <= b1.x && b2.x >= a1.x) {
                        collisionX = b2.x;
                    }
                } else {
                    if (a2.x <= a1.x && a2.x >= b1.x) {
                        collisionX = a2.x;
                    } else if (b2.x <= a1.x && b2.x >= b1.x) {
                        collisionX = b2.x;
                    }
                }
            }
        } else {
            if (a1.x === a2.x) {
                collisionX = a1.x;
                if (a1.y < b1.y) {
                    if (a2.y <= b1.y && a2.y >= a1.y) {
                        collisionY = a2.y;
                    } else if (b2.y <= b1.y && b2.y >= a1.y) {
                        collisionY = b2.y;
                    }
                } else {
                    if (a2.y <= a1.y && a2.y >= b1.y) {
                        collisionY = a2.y;
                    } else if (b2.y <= a1.y && b2.y >= b1.y) {
                        collisionY = b2.y;
                    }
                }
            }
        }
    }
    if (collisionX != null && collisionY != null) {
        console.log("player collision occured at " + "(" + collisionX + "/" + collisionY + ")");
        playerAlive = false;
    }
}

function checkForDirection(a, b) {
    if (a.y === b.y) {
        return "horizontal";
    } else {
        return "vertical";
    }
}

function horizontal(a1, b1, a2, b2) {
    if (a1.x < b1.x) {
        if (a2.x <= b1.x && a2.x >= a1.x) {
            return a2.x;
        }
    } else {
        if (a2.x <= a1.x && a2.x >= b1.x) {
            return a2.x;
        }
    }
}

function vertical(a1, b1, a2, b2) {
    if (a2.y < b2.y) {
        if (a1.y <= b2.y && a1.y >= a2.y) {
            return a1.y;
        }
    } else {
        if (a1.y <= a2.y && a1.y >= b2.y) {
            return a1.y;
        }
    }
}