Java 凸包-确定点的顺序
所以我在学习凸包算法,写所有的算法,从一个天真的蛮力到格雷厄姆扫描 这是我的Bruteforce O(n^4)算法。在开始时,假设所有点都是外壳的一部分。对于每个可能的三角形,消除位于三角形内的所有点。最终,那些未被消除的点将成为船体的一部分 以下是Java代码(已修复:使用Thomash的解决方案)Java 凸包-确定点的顺序,java,algorithm,convex-hull,convex-polygon,Java,Algorithm,Convex Hull,Convex Polygon,所以我在学习凸包算法,写所有的算法,从一个天真的蛮力到格雷厄姆扫描 这是我的Bruteforce O(n^4)算法。在开始时,假设所有点都是外壳的一部分。对于每个可能的三角形,消除位于三角形内的所有点。最终,那些未被消除的点将成为船体的一部分 以下是Java代码(已修复:使用Thomash的解决方案) public List naive(列表点){ 如果(点==null) 返回集合。emptyList(); if(points.size()角度1) 返回-1; 返回0; } } 我试图直观地看
public List naive(列表点){
如果(点==null)
返回集合。emptyList();
if(points.size()角度1)
返回-1;
返回0;
}
}
我试图直观地看到这些点,它们似乎是正确的,但是我不知道如何建立点的顺序来绘制凸包多边形?非常感谢您的帮助。如果您正在使用蛮力来查找哪些点是船体的一部分,那么您最好继续做一些丑陋的事情来查找点的顺序
<>你必须在胡胡胡绕时调整目标角度,但这是有效的(而且是在纸上做的一种方法)。< /P> < P>在凸壳和另一点A中取一点O。对于凸包中的每个B,用这些角度计算角度A和B点(如果A B<A B’,然后我们考虑B<B’)。我没有用这些角度得到排序点,我最终使用了你的方法,使用了一个比较器来测量相对于原点的角度。将编辑我的问题以包含代码。谢谢。:)我是否可以消除
Math.atan2
而只使用斜率?我想那会使它更快\@st0le:你应该能够避开坡度,是的。如果你这样做,就不需要首先将船体的一部分点与其他点分开。@NicolasRepiquet:是的,但是如果你碰巧在凸面船体上有一组点,这比从头开始做要快。@Li aungYip,虽然我理解你的方法,我使用了Thomash的方法,因为它的实现非常简单。我对你的两个解决方案都投了赞成票,但我会接受他的。再次感谢!:)
public List<Point> naive(List<Point> points) {
if (points == null)
return Collections.emptyList();
if (points.size() <= 3)
return points;
boolean[] extremePoints = new boolean[points.size()];
Arrays.fill(extremePoints, true);
for (int i = 0, sz = points.size(); i < sz; i++) {
if (extremePoints[i])
for (int j = 0; j < sz; j++) {
if (i != j && extremePoints[j]) {
for (int k = 0; k < sz; k++) {
if (k != i && k != j) {
for (int l = 0; l < sz; l++) {
if (extremePoints[l] && l != i && l != j
&& l != k) {
// Check if P[l] lies in triangle formed
// by
// P[i],P[j],P[k]
Polygon p = new Polygon();
p.addPoint(points.get(i).x,
points.get(i).y);
p.addPoint(points.get(j).x,
points.get(j).y);
p.addPoint(points.get(k).x,
points.get(k).y);
if (p.contains(points.get(l)))
extremePoints[l] = false;
}
}
}
}
}
}
}
Point centerOfHull = null; // Arbitrary point inside the hull
// Order?
for (int i = 0; i < extremePoints.length; i++) {
if (!extremePoints[i]) {
centerOfHull = points.get(i);
break;
}
}
List<Point> convexHull = new ArrayList<Point>();
for (int i = 0; i < extremePoints.length; i++) {
if (extremePoints[i]) {
convexHull.add(points.get(i));
}
}
Collections.sort(convexHull, new PointComp(centerOfHull));
// or use a heap. still O(nlogn)
return convexHull;
}
private class PointComp implements Comparator<Point> {
private Point center;
public PointComp(Point center) {
this.center = center;
}
@Override
public int compare(Point o1, Point o2) {
double angle1 = Math.atan2(o1.y - center.y, o1.x - center.x);
double angle2 = Math.atan2(o2.y - center.y, o2.x - center.x);
if (angle1 < angle2)
return 1;
else if (angle2 > angle1)
return -1;
return 0;
}
}