그래서 볼록 선체 알고리즘에 대해 배우고 순진한 Bruteforce에서 Graham Scan까지 모든 알고리즘을 작성합니다.볼록 선체 - 점의 순서를 결정합니다.
이것은 내 Bruteforce O (n^4) 알고리즘입니다. 처음에는 모든 점이 선체의 일부라고 가정합니다. 가능한 한 각 삼각형에 대해 삼각형 내부에있는 모든 점을 제거하십시오. 끝 부분에서 제거되지 않은 포인트는 선체의 일부가됩니다. 나는 시각적으로 이러한 점을보고, 그들이 올바른 것 같다 시도, 그러나 나는 점의 순서를 설정하는 방법을 모르는
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;
}
}
:
여기에 자바 코드 (Thomash의 솔루션 고정이)입니다 볼록 선체 다각형을 그리는거야? 어떤 도움을 주셔서 감사합니다.
좀 더 자세히 설명해 주시겠습니까? 나는이 각도를 사용하여 정렬 점을 얻지 못했습니다. – st0le
여러분의 방법을 사용하여 결과를 얻었습니다. 각도를 원점으로 측정 한 Comparator를 사용했습니다. 코드를 포함하도록 내 질문을 편집합니다. 감사. :) – st0le
어쨌든'Math.atan2'을 없애고 경사면을 사용할 수 있습니까? 나는 그것이 더 빨라질 것이라고 생각합니다. : \ – st0le