Search code examples
javascriptpolygoncollision

Polygon Collision Javascript


The collision Function doesn't work, i don't know why... Every other function should work, the drawing on the canvas has been tested. It returns 0 but in this example the two polygons collide.

If you need more Details write it in the comments...

       <script type='text/javascript'>
        var canvas = document.getElementById("c");
        var ctx = canvas.getContext('2d');

        var coordinates = new Array();
        var newCoordinate = new Array("4/2", "20/80", "50/30", "40/8");
        coordinates.push(newCoordinate);

        var newCoordinate = new Array("30/50", "60/80", "90/30", "70/8");
        coordinates.push(newCoordinate);



        drawPolygonFromArray(coordinates[0], ctx, '#f00');
        drawBoundingFromArray(coordinates[0], ctx, 'rgba(255,0,0,0.5)');

        drawPolygonFromArray(coordinates[1], ctx, '#0f0');
        drawBoundingFromArray(coordinates[1], ctx, 'rgba(0,255,0,0.5)');


        function drawPolygonFromArray(coordinates, c, color) {
            if (color == undefined) color = '#f00';
            c.fillStyle = color;
            c.beginPath();
            var splitted = coordinates[0].split("/");
            c.moveTo(parseInt(splitted[0]), parseInt(splitted[1]));

            for (var i = 1; i < coordinates.length; i++) {
                var splitted = coordinates[i].split("/");
                c.lineTo(parseInt(splitted[0]), parseInt(splitted[1]));

            }
            var splitted = coordinates[0].split("/");
            c.lineTo(parseInt(splitted[0]), parseInt(splitted[1]));
            c.closePath();
            c.fill();
        }

        function drawBoundingFromArray(coordinates, c, color) {
            if (color == undefined) color = '#f00';

            c.fillStyle = color;
            c.beginPath();
            var splitted = getTopLeftCoordinate(coordinates).split("/");

            ctx.rect(parseInt(splitted[0]), parseInt(splitted[1]), getWidthOfPolygon(coordinates), getHeightOfPolygon(coordinates));

            c.closePath();
            c.fill();
        }


        function getWidthOfPolygon(pCoordinates, minX) {
            if(minX == undefined) var minX = 999999999999;
            maxX = -1;

            for (var i = 0; i < pCoordinates.length; i++) {
                var splitted = pCoordinates[i].split("/");
                if (parseInt(splitted[0]) < minX) minX = parseInt(splitted[0]);
                if (parseInt(splitted[0]) > maxX) maxX = parseInt(splitted[0]);
            }

            return maxX - minX;
        }

        function getHeightOfPolygon(pCoordinates, minY) {
            if(minY == undefined) var minY = 999999999999;
            maxY = -1;
            for (var i = 0; i < pCoordinates.length; i++) {
                var splitted = pCoordinates[i].split("/");
                if (parseInt(splitted[1]) < minY) minY = parseInt(splitted[1]);
                if (parseInt(splitted[1]) > maxY) maxY = parseInt(splitted[1]);
            }
            return maxY - minY;
        }

        function getTopLeftCoordinate(pCoordinates) { // returns "x/y"
            minX = 999999999999;
            minY = 999999999999;

            for (var i = 0; i < pCoordinates.length; i++) {
                var splitted = pCoordinates[i].split("/");

                if (parseInt(splitted[0]) < minX) minX = parseInt(parseInt(splitted[0]));
                if (parseInt(splitted[1]) < minY) minY = parseInt(parseInt(splitted[1]));
            }
            return minX + "/" + minY;
        }

        function getAllCoordinates(pCoordinates) { // returns "x/y"
            coordinates = new Array();

            for (var i = 0; i < pCoordinates.length; i++) {
                var splitted = pCoordinates[i].split("/");

                coordinates.push(splitted[0]+"/"+splitted[1]);
            }
            return coordinates;
        }

        function collision(p1, p2) {
            //bounding boxes

            var splitted = getTopLeftCoordinate(p1).split("/");

            var x1 = parseInt(splitted[0]); var y1 = parseInt(splitted[1]); var w1 = getWidthOfPolygon(p1);
            var h1 = getHeightOfPolygon(p1);

           splitted = getTopLeftCoordinate(p2).split("/");

            var x2 = parseInt(splitted[0]); var y2 = parseInt(splitted[1]); var w2 = getWidthOfPolygon(p1);
            var h2 = getHeightOfPolygon(p2);

            var coo1 = getAllCoordinates(p1);
            var coo2 = getAllCoordinates(p2);

            for(var a = 0; a<p1.length; a++) {
                var splitted = coo1[a].split("/");

                var x = parseInt (splitted[0]);
                var w = parseInt(getWidthOfPolygon(p1, x));
                var y = parseInt (splitted[1]);
                var h = parseInt (getHeightOfPolygon(p1, y));

                for(var b = 0; b<p2.length; b++) {
                var splitted2 = coo2[b].split("/");

                var x1 = parseInt(splitted2[0]);
                var w1 = parseInt (getWidthOfPolygon(p2, x1));
                var y1 = parseInt(splitted2[1]);
                var h1 = parseInt (getHeightOfPolygon(p2, y1));
                alert(a + " " + x + " " + x1 + " " +y + " " + y1 + " " + h + " " + w + " " + (x1 + w));
                if (x >=x1 && x<= x1+w && y>=y1 && y<=y1+h) return 1;
                }
            }
            return 0;
        }
        alert(collision(coordinates[0],coordinates[1]));

Solution

  • It works now: JSFiddle: http://jsfiddle.net/sh3rlock/2LfUA/

       var canvas = document.getElementById("c");
        var ctx = canvas.getContext('2d');
    
        var coordinates = new Array();
        var coordinates = [
            [
                [4, 2],
                [20, 80],
                [50, 30],
                [40, 8]
            ],
            [
                [50, 20],
                [60, 80],
                [90, 31],
                [70, 50]
            ]
        ];
    
        drawPolygonFromArray(coordinates[0], ctx, '#f00');
        drawBoundingFromArray(coordinates[0], ctx, 'rgba(255,0,0,0.5)');
    
        drawPolygonFromArray(coordinates[1], ctx, '#0f0');
        drawBoundingFromArray(coordinates[1], ctx, 'rgba(0,255,0,0.5)');
    
    
        function drawPolygonFromArray(coordinates, c, color) {
            if (typeof color === "undefined") color = '#f00';
            c.fillStyle = color;
            c.beginPath();
            c.moveTo(coordinates[0][0], coordinates[0][1]);
    
            for (var i = 1; i < coordinates.length; i++) {
                c.lineTo(coordinates[i][0], coordinates[i][1]);
    
            }
            c.lineTo(coordinates[0][0], coordinates[0][1]);
            c.closePath();
            c.fill();
        }
    
        function drawBoundingFromArray(coordinates, c, color) {
            if (typeof color === "undefined") color = '#f00';
    
            c.fillStyle = color;
            c.beginPath();
            var topleft = getTopLeftCoordinate(coordinates);
    
            ctx.rect(topleft[0], topleft[1], getWidthOfPolygon(coordinates), getHeightOfPolygon(coordinates));
    
            c.closePath();
            c.fill();
        }
    
    
    
        function getAllCoordinates(pCoordinates) { // returns "x/y"
            coordinates = new Array();
    
            for (var i = 0; i < pCoordinates.length; i++) {
                var coords = pCoordinates[i];
    
                coordinates.push([coords[0], coords[1]]);
            }
            return coordinates;
        }
    
        function linehits(p1, p2, p3) {
            var x1 = p1[0];
            var y1 = p1[1];
            var x2 = p2[0];
            var y2 = p2[1];
            var a = (-(y1 - y2)) / (x2 - x1); // A von der Gerade P1-P2
            var c = (x2 * y1 - x1 * y2) / (x2 - x1); // C von der Gerade P1-P2
    
            if (typeof p4 === "undefined") {
                //alert();
                var a2 = 0;
                var c2 = p3[1]; // y-Punkt des P3
    
                var xS = (c2 - c) / a; // X-Schnittpunkt
                var yS = a * xS + c; // Y-SchnittPunkt
    
                if (((xS < p2[0] && xS > p1[0]) || (xS > p2[0] && xS < p1[0])) && xS < p3[0] && (yS < p2[1] || yS < p1[1])) return [xS, yS];
    
            } else {
                x1 = p3[0];
                y1 = p3[1];
                x2 = p4[0];
                y2 = p4[1];
                var a2 = (-(y1 - y2)) / (x2 - x1); // A von der Gerade P1-P2
                var c2 = (x2 * y1 - x1 * y2) / (x2 - x1); // C von der Gerade P1-P2
                var xS = (c2 - c) / (a - a2); // X-Schnittpunkt
                var yS = a * xS + c; // Y-SchnittPunkt
    
                if (((xS < p2[0] && xS > p1[0]) || (xS > p2[0] && xS < p1[0])) && xS < p3[0] && (yS < p2[1] || yS < p1[1])) return [xS, yS];
    
            }
    
            return 888;
    
    
        }
    
        function drawALine(p1, p2, c) {
            c.beginPath();
            c.moveTo(p1[0], p1[1]);
    
            for (var i = 1; i < coordinates.length; i++) {
                c.lineTo(p2[0], p2[1]);
    
            }
            c.stroke();
            c.closePath();
        }
    
        function pgIntersectsPg(p1, p2) { // p1 means Array with points [[0,6],[20,90],...,[10,8]]
            for (a = 0; a < p1.length; a++) {
                var point3 = p1[a];
                var hits = 0;
                for (b = 0; b < p2.length; b++) {
                    var point1 = p2[b];
                    var point2 = 0.0;
    
                    if (b < p2.length - 1) {
                        point2 = p2[b + 1];
                    } else {
                        point2 = p2[0];
                    }
                    if (linehits(point1, point2, point3).length == 2) {
                        hits++;
                    }
                    //alert(linehits(point1,point2,point3));
                }
                if (hits % 2 > 0) return 1;
            }
    
            for (a = 0; a < p2.length; a++) {
                var point3 = p2[a];
                //alert(hits);
                var hits = 0;
                for (b = 0; b < p1.length; b++) {
                    var point1 = p1[b];
                    var point2 = 0.0;
    
                    if (b < p1.length - 1) {
                        point2 = p1[b + 1];
                    } else {
                        point2 = p1[0];
                    }
                    if (linehits(point1, point2, point3).length == 2) {
                        hits++;
                        drawALine(point1, point2, ctx)
                        //alert([0,point3[1]] + " " +point3);
                        //drawALine([0,point3[1]],point3);
                    }
                    //alert(linehits(point1,point2,point3));
                }
                drawALine([0, point3[1]], point3, ctx);
                if (hits % 2 > 0) return 1;
            }
    
    
    
            return 0;
        }
    
        alert("Test: " + pgIntersectsPg(coordinates[0], coordinates[1]));