0

I have following coordinates in this nested array that generate a path for each of those players. They're all straight lines at right angles. Now the problem is that I don't have any methods in mind that allow me to calculate the coordinates of any potential intersections between each of those paths in case they overlap.

Does anyone knows of a Javascript method that allows me to calculate any intersections between a dynamic number of paths each with a different amount of coordinate sets?

Here's how it looks like in the frontend just to give you a picture:

How it looks in the frontend

Here's the array code that I use to generate the paths on a 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
        }]
    }]
}];

Btw, this is my first Stackoverflow Questions & thanks for helping me out!

im1tta
  • 31
  • 5
  • Parse each of the arrays and see if there's an intersection with any of the other array's co-ordinates. Since they're all straight lines at right angles this is simple - I was expecting something difficult from the description. Have you tried this yourself? – Reinstate Monica Cellio Feb 12 '18 at 15:57
  • Hi there, I've tried it out myself but I'm not a big expert in these kinds of Javascript methods and yes these are all straight lines and at right angles. Regarding your feedback: What do you exactly mean with "Parse each of the arrays and see if there's an intersection with any of the other array's co-ordinates." do you have an example? :) – im1tta Feb 12 '18 at 16:08
  • Why is prop an array if it's only holding one member that's actually holding the coordinates? Can you flatten that out? – dav1dhunt Feb 12 '18 at 16:19
  • You can take all the path arrays and turn them into one array, then loop that array and see if any lines cross. – Reinstate Monica Cellio Feb 12 '18 at 16:19
  • You might want to check out [this answer](https://stackoverflow.com/a/565282/3297291) for the Math and [this javascript implementation linked in its comments](https://github.com/pgkelley4/line-segments-intersect/blob/master/js/line-segments-intersect.js) – user3297291 Feb 12 '18 at 17:30
  • @user3297291 Thanks! That one was actually useful and helped me to solve the problem. – im1tta Feb 15 '18 at 15:19

1 Answers1

1

I've solved the problem, it took me awhile to understand the concept, but it is quite simple my case because the lines are all in a right angle.

Here's my solution, it is probably not the best solution to this but it works perfectly fine, even in a high frequency loop:

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;
        }
    }
}
im1tta
  • 31
  • 5