2D点的天际线 - 划分和征服算法

时间:2018-04-01 23:08:51

标签: java algorithm geometry points divide

我正在开展一个项目,我必须找到不受该组中任何其他点支配的点的天际线。如果x1 <= x2&amp;&amp;和点,则点A(x1,y1)支配点B(x2,y2)。 Y1,LT = Y2。 Here's an example

这是我的代码:

public static ArrayList<Point> findSkyline(ArrayList<Point> pointsList){
    if (pointsList.size()<=1){
        return pointsList;
    }

    ArrayList<Point> leftSkylinePoints=new ArrayList<>();
    ArrayList<Point> rightSkylinePoints=new ArrayList<>();
    ArrayList<Point> leftPoints=new ArrayList<>();
    ArrayList<Point> rightPoints=new ArrayList<>();

    for (int i=0;i<pointsList.size()/2;i++){
        leftPoints.add(pointsList.get(i));
    }
    for (int i=pointsList.size()/2;i<pointsList.size();i++){
        rightPoints.add(pointsList.get(i));
    }

    leftSkylinePoints=findSkyline(leftPoints);
    rightSkylinePoints=findSkyline(rightPoints);

    int minY=1001;
    for (int i=0;i<leftSkylinePoints.size();i++){
        if (leftSkylinePoints.get(i).y<minY){
            minY=leftSkylinePoints.get(i).y;
        }
    }
    for (int i=0;i<rightSkylinePoints.size();i++){
        if (rightSkylinePoints.get(i).y>=minY){
            rightSkylinePoints.remove(i);
        }
    }

    System.out.println("MINY: "+minY);

    System.out.print("Left: ");
    for (int i=0;i<leftSkylinePoints.size();i++){
        System.out.print("("+leftSkylinePoints.get(i).x+","+leftSkylinePoints.get(i).y+") ");
    }
    System.out.println();
    System.out.print("Right: ");
    for (int i=0;i<rightSkylinePoints.size();i++){
        System.out.print("("+rightSkylinePoints.get(i).x+","+rightSkylinePoints.get(i).y+") ");
    }
    System.out.println();
    System.out.println();


    leftSkylinePoints.addAll(rightSkylinePoints);
    return leftSkylinePoints;
}

These are the results.

你可以看到点(6,2)似乎在天际线中,但它不应该是因为它应该在第二个for循环中被删除。有谁知道为什么会这样?谢谢!

*对于更多的积分,我得到了更多不应该存在但现在我想了解这种情况。

**点数根据其x值(升序)进行排序

1 个答案:

答案 0 :(得分:0)

好的,我已经理解了逻辑缺陷。它在这里:

@objc func image(_ image: UIImage, didFinishSavingWithError error: Error?, contextInfo: UnsafeRawPointer) {

    if let error = error {
        print("Error Saving ARKit Scene \(error)")
    } else {
        print("ARKit Scene Successfully Saved")
    }
}

当您移除一个点时,其余部分向左移动(据我所知 for (int i=0;i<rightSkylinePoints.size();i++){ if (rightSkylinePoints.get(i).y>=minY){ rightSkylinePoints.remove(i); 感觉),因此下一个(未经处理的)项目将获得当前索引i并被排除在进一步处理之外。

最简单的解决方案 - 使用remove循环并在发生删除时省略递增索引。

另一种方法 - 从较大的索引循环到较低的索引(似乎这样的方向不应该破坏算法)

while