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

时间:2018-02-12 15:52:18

标签: javascript arrays canvas path intersection

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

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

以下是为了给你一张照片而在前端看起来的样子:

astropy.Table.read

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

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
        }]
    }]
}];

顺便说一句,这是我的第一个Stackoverflow问题&谢谢你帮帮我!

1 个答案:

答案 0 :(得分:1)

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

这是我的解决方案,它可能不是最好的解决方案,但即使在高频循环中也能完美运行:

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;
        }
    }
}