迭代点域中的每个三角形

时间:2016-06-15 13:55:30

标签: java optimization foreach iteration

我有一种方法可以将点添加到随机,未连接点的字段中,下一个要添加的点必须位于三点之间绘制的最大空三角形内。该领域的四个角是要添加的第一个点。

我的问题是,我目前用于计算每个三角形的解决方案使用了四个嵌套的增强型for循环'(foreach样式),并且随着点数的累加需要很长时间。我正在寻找并行处理这个问题(可能使用Java 8并行流?),但有没有更有效的方法选择点或测试它们是否在三角形内?

非常感谢

for(Point p1 : POINTS) {
        for(Point p2 : POINTS) {
            if(p2==p1) {continue;}
            for(Point p3 : POINTS) {
                if(p3==p2 || p3==p1) {continue;}

                Polygon p = new Polygon(new int[]{p1.x,p2.x,p3.x}, new int[]{p1.y,p2.y,p3.y}, 3);//Construct a triangle from these points
                boolean empty = true;

                for(Point p4 : POINTS) {//test the remaining points if they are in the triangle
                    if(p4==p3 || p4 == p2 || p4 == p1) {continue;}
                    if(p.contains(p4)){
                        empty = false;
                        break;
                    }
                }
                if(empty==true) {
                    emptyTriangles.add(new Triplet<Point,Point,Point>(p1,p2,p3));//emptyTriangles contains the coordinates of the empty triangles
                }

            }
        }
    }

3 个答案:

答案 0 :(得分:1)

我认为你可以通过不再看一个组合来加速它(3个外部for循环)。例如,如果你有点{a,b,c},你的算法只需要1个组合(3个超过3个),但经过27个(3 ^ 3)并完全计算6个(3个超过3次3个!)。对于N个点,这变为N ^ 3次迭代和N *(N-1)*(N-2)计算,其中仅需要(N超过3)= N *(N-1)*(N-2)/ 6 。因此,因子6的加速是一个开始。

鉴于POINTS是一个数组,你可以写

for (int i1 = 0; i1 < POINTS.length-2; i1++) {
    for (int i2 = i1+1; i2 < POINTS.length-1; i2++) {
        for (int i3 = i2+1; i1 < POINTS.length; i3++) {
            ...
        }
    }
}

你不应该以相同的方式循环p4,因为三角形的顶点可以在你的算法之间互换,但要检查的点不是。

答案 1 :(得分:1)

因此,如果我理解正确,你会得到一个积分清单。然后将所有这些点循环以创建所有可能的三角形,并在最大三角形中放置一个随机点。

添加新点后,您无需再次实际计算所有内容。您只需计算使用新点的每个三角形。所有其他人都可以保存在某个地方。

答案 2 :(得分:0)

由于您知道多边形是三角形,因此您应该使用Polygon#contains()替换使用barycentric coordinates的算法来查找该点是否为三角形。这将更快,因为三角形包含点的规则比较大的多边形要简单得多。

此外,POINTS应该排序。这样,您只能迭代每个点之后的点。我目前无法想出一种方法来做到这不是O(n 2 )或以某种方式使用短路,但它是一个开始。 / p>