이번 문서의 목표: 윈도우 좌표를 뷰포트 좌표로 매핑하는 공식을 실제 점에 적용할 수 있고, Cohen-Sutherland 리전 코드와 Liang-Barsky 매개변수 방식으로 같은 선분을 각각 클리핑해 두 결과가 일치함을 확인할 수 있게 된다.
왜 화면 밖의 도형까지 계산하면 안 되는가
그래픽스 응용 프로그램은 보통 실제 세계 좌표(예: 지도 데이터, 3D 장면)로 도형을 정의한 뒤, 화면의 일부 사각형 영역에만 그 일부를 보여줍니다. 이때 두 가지 사각형을 구분해야 합니다. 윈도우(window)는 사용자가 보고 싶은 세계 좌표 안의 관심 영역이고, 뷰포트(viewport)는 그 내용을 실제로 표시할 화면(또는 화면 안의 한 영역) 좌표입니다. 예를 들어 지도 프로그램에서 위도·경도로 정의된 특정 구역(윈도우)을 골라, 그 구역을 1920×1080 픽셀 창(뷰포트)에 맞춰 그리는 것과 같습니다.
또한 윈도우 경계를 완전히 벗어난 도형까지 좌표 변환하고 픽셀을 계산하는 것은 낭비입니다. 화면에 보이지도 않을 도형을 끝까지 계산하면 성능이 크게 떨어지므로, 윈도우 경계를 기준으로 도형을 미리 잘라내는 절차가 필요합니다. 이것이 이번 편의 두 번째 주제인 클리핑(Clipping, 잘라내기)입니다.
쉽게 말하면: 윈도우-뷰포트 변환은 “보고 싶은 영역을 화면 크기에 맞게 늘이거나 줄이는 것”이고, 클리핑은 “그 영역 밖으로 나간 부분을 미리 잘라내는 것”입니다.
1. 윈도우-뷰포트 변환
세계 좌표계의 윈도우 범위를 라 하고, 화면(또는 화면 안 특정 영역)의 뷰포트 범위를 라고 하면, 윈도우 안의 점 를 뷰포트 좌표 로 옮기는 식은 다음과 같습니다.
- : 윈도우의 왼쪽 경계로부터 점이 얼마나 떨어져 있는지(윈도우 안에서의 상대 위치)
- : 윈도우 너비와 뷰포트 너비의 비율(배율). 이 비율을 상대 위치에 곱하면 뷰포트 안에서의 상대 위치가 된다.
- : 뷰포트의 왼쪽 경계 좌표를 더해 절대 좌표로 바꾼다.
좌표도 같은 구조로 계산합니다.
세계 좌표 윈도우가 이고, 이것을 화면 전체(뷰포트 )에 매핑한다고 하겠습니다. 윈도우 안의 점 이 뷰포트의 어느 좌표로 매핑되는지 계산해 보겠습니다.
- 윈도우 너비 이 뷰포트 너비 으로 매핑되므로 배율은 이고, 윈도우 높이 이 뷰포트 높이 으로 매핑되므로 배율은 이다.
- 결과: 윈도우 좌표 은 뷰포트 좌표 에 그려진다.
자주 틀리는 점: 윈도우와 뷰포트의 가로세로 배율이 다르면( 배율 , 배율 처럼) 도형이 원래 비율과 다르게 찌그러져 보입니다. 원래 형태를 유지하려면 두 배율을 같게 만들거나(가로세로 비율, 종횡비를 유지), 종횡비를 맞추기 위해 여백을 두는 처리가 추가로 필요합니다.
2. Cohen-Sutherland 알고리즘 — 리전 코드로 빠르게 걸러내기
쉽게 말하면: Cohen-Sutherland는 각 점이 클리핑 윈도우의 위·아래·왼쪽·오른쪽 중 어느 쪽 바깥에 있는지를 4비트 코드로 표시해, 계산 없이 바로 판정할 수 있는 경우를 먼저 걸러내는 방법입니다.
클리핑 윈도우를 라고 할 때, 평면 전체를 이 윈도우를 기준으로 9개의 영역(윈도우 내부 1개 + 주변 8개)으로 나눕니다. 각 영역에 4비트 리전 코드(region code)를 부여하는데, 각 비트는 다음을 의미합니다(왼쪽부터 위·아래·오른쪽·왼쪽 순서).
| 비트 위치 | 의미 | 조건 |
|---|---|---|
| 1번째(맨 위) | 위쪽(top) | |
| 2번째 | 아래쪽(bottom) | |
| 3번째 | 오른쪽(right) | |
| 4번째(맨 끝) | 왼쪽(left) |
예를 들어 윈도우보다 왼쪽에 있으면서 위쪽에도 있는 점은 1001(위=1, 아래=0, 오른쪽=0, 왼쪽=1)이 되고, 윈도우 내부에 있는 점은 네 조건이 모두 거짓이므로 0000이 됩니다.
두 점의 리전 코드를 구했으면 다음 두 가지 빠른 판정을 먼저 시도합니다.
- 완전히 안쪽(trivial accept): 두 코드를 OR(비트별 논리합) 했을 때
0000이 나오면, 두 점 모두 내부에 있다는 뜻이므로 선분 전체가 보이는 상태다. 클리핑 계산 없이 그대로 그린다. - 완전히 바깥쪽(trivial reject): 두 코드를 AND(비트별 논리곱) 했을 때
0000이 아니면, 두 점이 같은 쪽 바깥에 함께 있다는 뜻이므로 선분 전체가 보이지 않는다. 계산 없이 버린다.
두 판정 모두 해당하지 않으면(OR가 0000이 아니고 AND도 0000인 경우), 선분이 윈도우 경계와 실제로 교차할 가능성이 있으므로 교차점을 계산해 선분을 잘라내야 합니다.
클리핑 윈도우를 이라 하고, 선분의 두 끝점을 , 이라고 하겠습니다.
리전 코드 계산. : 이므로 왼쪽 비트만 1, 나머지는 0 → 코드 0001. : 이므로 위쪽 비트만 1, 나머지는 0 → 코드 1000.
- OR가
0000이 아니므로 완전히 안쪽은 아니다. - AND가
0000이므로 완전히 바깥쪽도 아니다. - 따라서 실제 교차점을 계산해야 한다.
교차점 계산. 코드가 0000이 아닌 점부터 처리합니다. 먼저 의 왼쪽 비트가 켜져 있으므로 왼쪽 경계 과의 교차점을 구합니다. 직선의 기울기는 다음과 같습니다.
- 일 때 이므로 새 점 을 얻는다. 의 리전 코드를 다시 계산하면 은 과 같아 왼쪽 조건을 만족하지 않고(
x < xmin조건이므로 등호는 포함되지 않음), 도 윈도우 안에 있으므로 코드는0000이 되어 내부로 판정된다.
이제 의 위쪽 비트가 켜져 있으므로 위쪽 경계 과의 교차점을 구합니다. 이번에는 갱신된 점 과 을 잇는 선분을 기준으로 계산합니다.
- 새 점 을 얻는다. 리전 코드를 다시 계산하면 은 와 같아 위쪽 조건(등호 제외)을 만족하지 않고 도 윈도우 안에 있으므로 코드는
0000이 되어 내부로 판정된다.
두 점 모두 0000이 되었으므로(OR = 0000), 클리핑이 끝났습니다. 최종적으로 화면에 그려지는 선분은 원래의 –이 아니라, 잘려진 –입니다.
| 단계 | 대상 점 | 코드 | 판정 | 처리 |
|---|---|---|---|---|
| 1 | , | 0001, 1000 | trivial accept·reject 모두 아님 | 교차점 계산 필요 |
| 2 | (왼쪽 비트) | – | 경계와 교차 | , 코드 0000 |
| 3 | (위쪽 비트) | – | 경계와 교차 | , 코드 0000 |
| 4 | , | 0000, 0000 | OR = 0000 → trivial accept | 클리핑 종료, – 출력 |
자주 틀리는 점: 교차점을 계산한 뒤 리전 코드를 다시 계산하지 않고 바로 다음 경계로 넘어가는 실수가 흔합니다. 한 번 잘라낸 뒤에는 반드시 새 점의 리전 코드를 다시 구해, 아직 밖에 있는지 이제 안에 들어왔는지 확인한 다음 절차를 반복해야 합니다.
3. Liang-Barsky 알고리즘 — 매개변수 방정식으로 한 번에 계산
쉽게 말하면: Liang-Barsky는 선분을 매개변수 로 표현한 뒤, 네 변과 만나는 값의 범위를 구해 교집합만 남기는 방법입니다.
선분 위의 점을 매개변수 ()로 표현하면 다음과 같습니다.
- ,
- 이면 시작점 , 이면 끝점 를 가리킨다.
이 선분이 윈도우의 네 변(왼쪽·오른쪽·아래쪽·위쪽)과 어디서 만나는지를 각각 값으로 구하고, 그 중 “선분이 윈도우 안으로 들어가는 지점들” 중 가장 늦게 들어가는 를 , “윈도우 밖으로 나가는 지점들” 중 가장 먼저 나가는 를 로 잡습니다. 네 변에 대해 다음 값을 계산합니다.
- 인 항목은 “선분이 윈도우 안으로 들어가는 방향”이므로 가 후보가 된다.
- 인 항목은 “선분이 윈도우 밖으로 나가는 방향”이므로 가 후보가 된다.
앞서 Cohen-Sutherland에서 사용한 같은 값(윈도우 , 선분 –, )으로 계산해 보겠습니다.
| 변 | 후보 종류 | |||
|---|---|---|---|---|
| 왼쪽 | 후보() | |||
| 오른쪽 | 후보() | |||
| 아래쪽 | 후보() | |||
| 위쪽 | 후보() |
- 이므로 선분의 구간이 윈도우 안에 보인다. 만약 였다면 선분 전체가 윈도우 밖에 있다는 뜻이므로 버린다.
이제 와 를 원래 매개변수 방정식에 대입해 실제 좌표를 구합니다.
- 결과: 클리핑된 선분은 에서 까지다. 이는 앞서 Cohen-Sutherland 알고리즘으로 구한 결과와 정확히 일치한다. 두 알고리즘 모두 같은 기하학적 문제를 풀기 때문에 계산 과정은 다르지만 최종 결과는 같아야 하며, 서로 다른 방법으로 검산하는 습관은 실전 계산 문제에서 실수를 줄여준다.
자주 틀리는 점: 인 경우(선분이 해당 변과 평행한 경우)를 빠뜨리는 실수가 있습니다. 이면서 이면 선분이 그 변의 바깥쪽과 평행하다는 뜻이므로 선분 전체를 버려야 하고, 이면 그 변에 대한 제약이 없다는 뜻이므로 해당 항목은 범위 계산에서 제외합니다.
4. Cohen-Sutherland와 Liang-Barsky 비교
| 구분 | Cohen-Sutherland | Liang-Barsky |
|---|---|---|
| 기본 아이디어 | 4비트 리전 코드로 완전 내부·완전 외부를 빠르게 판정 | 매개변수 의 유효 구간을 부등식으로 계산 |
| 반복 횟수 | 완전히 판정될 때까지 교차점 계산을 반복(선분마다 다름) | 를 한 번의 비교 과정으로 계산 |
| 계산 효율 | 완전 내부·외부 선분에서 매우 빠름(비트 연산) | 여러 변과의 교차를 한 번에 처리해 반복이 적음 |
| 확장성 | 3D로 확장하려면 6비트 코드(앞·뒤 조건 추가)로 확장 | 3D로 확장하기 비교적 자연스러움(매개변수 개념 유지) |
두 알고리즘 모두 “완전 내부”, “완전 외부”, “부분적으로 겹침”이라는 세 가지 상황을 구분해서 처리한다는 공통점이 있습니다. 실전에서는 리전 코드 방식이 이해하기 쉬워 먼저 배우고, 매개변수 방식은 사각형 클리핑 외에 다른 볼록 다각형 클리핑으로 확장할 때 더 유리한 구조를 가집니다.
핵심 정리
- 윈도우-뷰포트 변환은 세계 좌표의 윈도우 범위를 화면의 뷰포트 범위로 비율에 맞춰 매핑하며, 가로세로 배율이 다르면 도형이 찌그러진다.
- Cohen-Sutherland는 위·아래·오른쪽·왼쪽 4비트 리전 코드를 이용해 완전 내부(OR=0000)와 완전 외부(AND≠0000)를 빠르게 판정하고, 나머지는 경계와의 교차점을 반복 계산한다.
- Liang-Barsky는 선분을 매개변수 로 표현하고, 네 변에 대한 를 구해 교집합 구간만 남긴다.
- 같은 선분에 두 알고리즘을 적용하면 결과가 일치해야 하며, 이는 계산을 검산하는 좋은 방법이다.