按极角排序

时间:2019-01-13 15:33:54

标签: java sorting convex-hull grahams-scan

我正在尝试为Java中的凸包实现Graham’s Scan algorithm,并且在相对于y值最低的点按极角对点进行排序时遇到了麻烦。

我找到了this的答案,并了解了如何计算极角,但没有对点进行排序。

我已经看到正在使用Collections.sort()的实现,但是它们似乎都不适合我想使用的Point2D类,因为我希望能够将double用作坐标。

基本上,我希望能够通过ArrayList<Point2D>的极角对同一ArrayList中y值最低的点进行排序。

有人可以帮我吗?谢谢。

2 个答案:

答案 0 :(得分:1)

让我们假设initial是具有最低Y坐标的Point2D。另外,我们假设List<Point2D> points是一个具有所有其他可用点的列表,但其中不包含initial点。

为了对列表进行排序,我们可以将Collections.sort与比较器一起使用:

Collections.sort(points, (a, b) -> {
    double cotanA = -(a.getX() - initial.getX()) / (a.getY() - initial.getY());
    double cotanB = -(b.getX() - initial.getX()) / (b.getY() - initial.getY());
    if (cotanA - cotanB < 0) {
        return 1;
    }
    return -1;
});

答案 1 :(得分:0)

我修改了这个问题的最后答案。

Point定义一个新类:

class Point {
    private long x, y;
    Point(long x, long y) {
        this.x = x;
        this.y = y;
    }
    Point() {
        x = 0;
        y = 0;
    }
    public long getX() {
        return x;
    }
    public long getY() {
        return y;
    }
}

定义一个用于计算两个向量的叉积的新函数:

public long cross(long x1, long y1, long x2, long y2) {
    return x1 * y2 - x2 * y1;
}

让我们假设initial是具有最低Y坐标的Point。另外,我们假设List<Point> points是一个具有所有其他可用点的列表,但其中不包含initial点。

为了对列表进行排序,我们可以将Collections.sort与比较器一起使用:

Collections.sort(points, (a, b) -> {
    long cr = cross(a.getX() - initial.getX(), a.getY() - initial.getY(), b.getX() - initial.getX(), b.getY() - initial.getY());
    if (cr > 0)
        return 1;
    else
        return -1;
});

在此解决方案中,我们使用叉积检查两个矢量是顺时针还是逆时针定位。 该解决方案有两个好处:

  1. 当我们的坐标是整数时,它更珍贵。在其他解决方案中计算角度时,浮点计算可能会出现一些错误。
  2. 在其他解决方案中,我们可能会采用“除以零”的方法,但是这里没有这个问题。
相关问题