多边形碰撞Javascript

时间:2014-06-01 18:50:11

标签: javascript polygon collision

碰撞功能不起作用,我不知道为什么......  每个其他功能都应该工作,画布上的绘图已经过测试。  它返回0但在这个例子中两个多边形碰撞。

如果您需要更多详细信息,请在评论中写下...

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

1 个答案:

答案 0 :(得分:0)

现在有效: 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]));