我正在尝试为Java中的凸包实现Graham’s Scan algorithm,并且在相对于y值最低的点按极角对点进行排序时遇到了麻烦。
我找到了this的答案,并了解了如何计算极角,但没有对点进行排序。
我已经看到正在使用Collections.sort()
的实现,但是它们似乎都不适合我想使用的Point2D类,因为我希望能够将double用作坐标。
基本上,我希望能够通过ArrayList<Point2D>
的极角对同一ArrayList中y值最低的点进行排序。
有人可以帮我吗?谢谢。
答案 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;
});
在此解决方案中,我们使用叉积检查两个矢量是顺时针还是逆时针定位。 该解决方案有两个好处: