だから私は凸包アルゴリズムについて学んでいて、単純なブルートフォースからグラハム スキャンまでのすべてのアルゴリズムを書き上げています。
これは私のブルートフォース O(n^4) アルゴリズムです。最初に、すべてのポイントが船体の一部であると想定します。可能な三角形ごとに、三角形の内側にあるすべての点を削除します。最終的に、排除されなかったポイントは船体の一部になります。
Javaコードは次のとおりです(修正済み: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;
}
}
これらの点を視覚的に見てみましたが、正しいようですが、凸包ポリゴンを描画するための点の順序を確立する方法がわかりませんか? どんな助けでも大歓迎です。