평면 상에 주어진 점들의 convex hull을 구하는 알고리즘 중의 하나인 Graham scan에서는 먼저 주어진 점들을 한 점을 기준으로 각도로 정렬하는 과정이 필요했다. 그러면 점들이 순차적으로 연결된 단순 다각형에서는 sorting과정이 없이 Graham scan 알고리즘을 바로 적용이 가능한 것일까? 이에 대한 counter example은 쉽게 찾을 수 있다. 단순 폴리곤에 대해서도 항상 각도에 대한 정렬 과정이 필요한 것인가? 답은 아니다. 정렬 과정이 없이도 단순 폴리곤에 대해서는 쉽게 convex hull을 구할 수 있는 알고리즘이 존재한다. 정렬 과정이 없이 단순 폴리곤의 convex hull을 찾는 알고리즘에 대해서 알아보자.
Melkman Algorithm;
우선 폴리곤의 이웃하는 세 꼭짓점을 잡아서, 반시계 방향의 삼각형을 구성한다. 이 삼각형을 deque에 넣는다 (bottom = top). 폴리곤을 순환하면서 새 점이 들어올 때 이미 만들어진 convex hull의 내부점이 아니면 이 점이 포함되도록 convex hull을 업데이트한다: Graham scan 알고리즘의 scanning 과정을 bottom을 기준으로 반시계 방향으로 convexity를 만족시킬 때까지 bottom을 제거하고, top을 기준으로는 시계방향으로 convexity를 만족시킬 때까지 top을 제거한다. 이 과정이 끝나면 새 점을 deque에 추가한다. 이 과정을 나머지 모든 점들에 대해서도 진행한다.
int LEFTSIDE(CPoint A, CPoint B, CPoint C){ // cross(AB, AC) > 0: C가 AB 대해서 왼쪽
return ((B.x - A.x) * (C.y - A.y) - (B.y - A.y) * (C.x - A.x)) > 0;
}
std::vector<CPoint> convexhull_spolygon(std::vector<CPoint>& pts) {
int N = pts.size();
if (N < 3) return std::vector<CPoint> (); //null_vector;
std::vector<CPoint> Q(2*N + 1); // deque;
int bot = N - 2, top = bot + 3;
// |0|1|......|N-2|N-1|N+0|N+1|N+2|..............|2N|;
// bot top
Q[bot] = Q[top] = pts[2];
if (LEFTSIDE(pts[0], pts[1], pts[2])) { //2->0->1->2; Q에 ccw로 입력;
Q[bot + 1] = pts[0]; Q[bot + 2] = pts[1];
} else {
Q[bot + 1] = pts[1]; Q[bot + 2] = pts[0];
}
int i = 2; // last touched index;
while (++i < N) {
// 기존의 convex_hull에 들어있으면 제외.
if (LEFTSIDE(Q[bot + 0], Q[bot + 1], pts[i]) &&
LEFTSIDE(Q[top - 1], Q[top + 0], pts[i]))
continue;
// bottom에 대해서 ccw 방향으로 체크(bot 증가 방향)
// pts[i]가 (bot)->(bot+1)라인의 오른쪽에 있으면, 기존의 bottom을 제외;
while (!LEFTSIDE(Q[bot], Q[bot + 1], pts[i]) && (bot < top)) bot++;
Q[--bot] = pts[i];
// 추가점에서 top->top-1의 ccw 방향으로 convexity 체크하여 만족하지 않은 경우
// top을 감소
while (!LEFTSIDE(Q[top - 1], Q[top], pts[i]) && (top > bot)) top-- ;
Q[++top] = pts[i];
}
if (bot > 0)
for (int i = 0; i < (top-bot); ++i) Q[i] = Q[i + bot];
Q.resize(top - bot); // Q[top] = Q[bot]
return Q;
};
728x90
'Computational Geometry' 카테고리의 다른 글
Minimum Enclosing Circle (0) | 2021.03.01 |
---|---|
Creating Simple Polygons (0) | 2021.01.25 |
단순 다각형의 무게중심 (0) | 2021.01.24 |
단순 다각형의 면적(2D) (0) | 2021.01.23 |
Binary Image에서 Convex Hull (0) | 2021.01.06 |