将多边形点数组转换为带孔的形状数组 - js

时间:2014-05-25 12:31:24

标签: javascript recursion polygon

问题的JSFiddle:http://jsfiddle.net/X8427/1/

我有一个像这样的多边形数组:

var pts = 
//array of shapes
[
    //array of shape coordinates
    [
        {
            X: 10,
            Y: 15
        },
        {
            X: 10,
            Y: 20
        },
        {
            X: 15,
            Y: 20
        },
        {
            X: 15,
            Y: 15
        }
    ],
    [
        {
            X: 11,
            Y: 16
        },
        {
            X: 11,
            Y: 19
        },
        {
            X: 14,
            Y: 19
        },
        {
            X: 14,
            Y: 16
        }
    ]
];

没有多边形边缘重叠,但我需要找出创建的多边形中有哪些(如果有的话)在另一个内部有空洞;所以这个输入数组最终看起来像这样:

[
    //array of shapes
    {
        //coordinates of outer shape
        outer: [
                    {
                        X: 10,
                        Y: 15
                    },
                    {
                        X: 10,
                        Y: 20
                    },
                    {
                        X: 15,
                        Y: 20
                    },
                    {
                        X: 15,
                        Y: 15
                    }
               ]
         //array of holes with in the outer shape
         holes: [
                    //array of hole coordinates
                    [
                         {
                             X: 11,
                             Y: 16
                         },
                         {
                             X: 11,
                             Y: 19
                         },
                         {
                             X: 14,
                             Y: 19
                         },
                         {
                             X: 14,
                             Y: 16
                         }
                    ]
               ]
     }
]

由于多边形的边缘不重叠,我可以检查是否只有一个多边形点位于具有此功能的另一个多边形内:

    function pointInPoly(poly, pt){
        for(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
            ((poly[i].Y <= pt.Y && pt.Y < poly[j].Y) || (poly[j].Y <= pt.Y && pt.Y < poly[i].Y))
            && (pt.X < (poly[j].X - poly[i].X) * (pt.Y - poly[i].Y) / (poly[j].Y - poly[i].Y) + poly[i].X)
            && (c = !c);
        return c;
    }
像这样:

var shapes = [];
for (var i = 0; i < pts.length; i++) {
    if (pts[i]) {
        var shape = {outer: pts[i], holes: []};

        for (var j = 0; j < pts.length; j++) {
            if (i != j && pointInPoly(pts[i], pts[j][0])) {
                shape.holes.push(pts[j]);
                pts[j] = false;
            }
        }

        shapes.push(shape);
    }
}
console.log(shapes);

这适用于测试数据,但是如果孔内有第三个多边形,那么它将作为一个孔添加到外部形状,但实际上它是第二个形状,它可能有自己的洞。我如何递归地使这个工作,所以我最终得到一个包含所有单独形状和孔的数组?

0 个答案:

没有答案