posted by cimple 2010. 1. 16. 16:46

 

CGAL Open Source Project 의 목적은, 효율적이고 신뢰할 수 있는 Geometric Algorithm 을 C++ 라이브러리 형태로 제공하는 데 있습니다.

 

 

CGAL 의 매뉴얼 형태

 

CGAL 의 Documentation 을 보면 Overview / Online Manual / Tutorials / All Manuals 로 나뉘어져 있습니다.

여기서 Overview 에 들어가면 크게 17개의 Part로 나뉘어져 있고, 각 Part 는 몇 개씩의Chapter 들이 있는데, 각 Chapter 마다 User Manual 과 Reference Manual 로 나뉘어져 있습니다.

User Manual 은 해당 Chapter 의 대략적인 설명과 함께 예제들이 나와 있고, Reference Manual 은 Class 와 Function 에 대한 자세한 설명들이 나와 있습니다.

 

 

 

CGAL 의 Hello World

 

CGAL 의 'Hello World' 라면서 가장 처음에 나오는 예제가 이것입니다.

 

 

뭔가 좀 황당하기도 한데… (그렇다고 CGAL 이 Hello World 를 찍는 것을 첫 번째 예제로 할 수도 없는 일이니)

CGAL 의 첫 입문은 5개 Point 의 Covex Hull 을 구하는 것부터 시작됩니다. 굉장히 간단한 프로그램처럼 보이지만, 생각보다 그렇게 간단하지는 않습니다.

먼저 CGAL의 Exact_predicates_inexact_constructions_kernel 이라는 커널을 K로 정의하고 그 K로부터 Point 2 를 정의합니다.

이 Point2 클래스의 객체 points 라는 녀석도 참 희한합니다. 일단 2D 평면좌표 2개를 가지고 초기화되는 클래스라는 사실은 알겠는데,

일단 convex_hull_2 라는 함수에서 convex hull 을 이루는 점을 반환하는 공간은 result 인데, 이 함수 전체가 리턴하는 값은 Point_2 의 포인터인 ptr 입니다.

Iterator 를 도는 것도, points 에서부터 points+5 를 돌면 points[5] 라는 배열 전체를 한바퀴 돈다고 하는데 이것도 잘 이해가 가지 않고,

ptr-result 를 하면 convex hull 을 이루고 있는 점들의 개수가 나온다는 것도 잘 이해가 가지 않습니다.

result 는 분명 convex hull 을 이루고 있는 점들입니다. result[0], result[1], result[2] 가 바로 convex hull 을 이루는 점들이었거든요.

 

설명을 해 보면 이렇습니다.

 

일단 Exact_predicates_inexact_constructions_kernel 이라는 커널은 실제로 지오메트리를 construct 해 주지는 않지만, 점들의 좌표 정보나 방향 등을 간단하게 알아보는 데 사용되는 커널입니다.

 

convex_hull_2 함수는 3개의 인수를 가지는데, input 의 시작점 포인터와, 마지막 점 바로 다음의 포인터, 그리고 결과물의 첫 포인터 입니다.

배열의 이름은 곧 포인터로 사용되기 때문에, 위의 예제에서 points 는 points[5] 배열의 첫 번째 요소, 즉 points[0] 을 의미하게 되겠고, 그 주소값을 가지고 있을 것입니다.

points[1] 의 주소값은 points+1 과 같습니다. 그러므로 points+5 는 points 배열이 끝나는 points[4] 의 바로 다음 주소지요. 마지막 점 바로 다음의 포인터입니다.

그리고 result 에 convex-hull 을 이루는 점들이 배열 형태로 저장되게 되고, result 는 동시에 그 배열의 첫 번째 요소를 가리키는 포인터입니다.

 

그리고 convex_hull_2 함수는 리턴하는 값이 있는데, convex hull 을 이루는 배열 바로 다음 주소의 포인터를 반환합니다.

따라서 ptr-result 를 하게 되면, ptr 의 주소값이 result 의 첫 번째 요소의 주소값으로부터 얼마나 떨어져 있는가를 알 수 있게 되고, 그로부터 result 의 크기를 알 수 있게 됩니다.

 

저 또한 포인터와 배열의 관계에 대해서 조금 불명확하게 알고 있었기 때문에 (사실 이 부분은 C 문법에 해당합니다) 조금 헷갈리는 부분이 있는데

보충 설명이 필요하다면 미팅 시간에 설명하도록 하겠습니다

 

 

다음은 같은 예제를 STL 을 사용하여 표현하는 방법입니다.

CGAL 의 Point_2 라는 클래스 자료형태를 vector 로 묶었습니다.

 

보시는 바와 같이, STL 로 Points 와 result 라는 벡터를 만듭니다.

그러면 convex_hull_2 함수가 벡터의 begin() 부터 end() 까지 iterator 를 돌면서 convex_hull 을 찾아주고, back_inserter 함수로 result 라는 벡터에 해당 결과들을 밀어 넣습니다.

이 result 의 크기만 측정하면 convex hull 을 이루는 점의 개수를 알 수 있겠죠. 이번에는 굳이 convex_hull_2 함수의 리턴값을 사용할 필요가 없을 것입니다.

 

 

 

마지막으로 유저로부터 입력받은 좌표로부터 convex hull 을 구하는 프로그램입니다.

이번에는 낯선 것이 'iterator' 라는 것을 include 하는군요.

 

 

실행 결과는 정말 신기합니다;;;

 

 

제가 이런 실행 결과를 원하면서 같은 프로그램을 만들었다면 for 문과 if 문의 향연이 되었을텐데, istream_iterator 와 ostream_iterator 로 이렇게 간결하고 멋진 프로그램이 작성이 가능합니다.

(STL 에 놀라고 있을 때가 아니라 CGAL 을 알아봐야 하는건데 이 무슨;;;)

 

 

좌우지간 Hello World 부터 쉽지만은 않습니다.

 

그렇다고 못할 것도 없죠.

 

ThEnd.