코언-서덜랜드 알고리즘
Cohen–Sutherland algorithm코헨-서덜랜드 알고리즘은 라인 클리핑에 사용되는 컴퓨터 그래픽 알고리즘이다.알고리즘은 2차원 공간을 9개 영역으로 나눈 다음, 관심의 중심 영역(뷰포트)에서 보이는 선의 선과 부분을 효율적으로 결정한다.
이 알고리즘은 1967년 대니 코헨과 이반 서덜랜드의 비행 시뮬레이터 작업 중에 개발되었다.[1]
알고리즘
알고리즘은 다음 중 어느 하나에 근거하여 선을 포함하거나 제외하거나 부분적으로 포함시킨다.
- 두 끝점이 모두 뷰포트 영역(점수 = 0000의 비트 OR): 사소한 수락.
- 두 엔드포인트 모두 적어도 하나의 보이지 않는 영역을 공유하며, 이는 선이 보이는 영역을 가로지르지 않음을 의미한다(비트 AND of Endpoints ≠ 0000): 사소한 거부.
- 두 끝점은 서로 다른 영역에 있다: 이 비비교적 상황의 경우 알고리즘은 뷰포트 영역 밖에 있는 두 점 중 하나를 찾는다(최소한 한 점이 외부에 있을 것이다).그런 다음 아웃포인트와 확장 뷰포트 테두리의 교차점(즉, 선에 대한 파라메트릭 방정식)을 계산하고 이 새로운 점이 아웃포인트를 대체한다.알고리즘은 사소한 수락이나 거부가 발생할 때까지 반복된다.
아래 그림의 숫자를 아웃코드라고 한다.아웃코드는 라인의 두 점 각각에 대해 계산된다.이 아웃코드는 2차원 클리핑을 위한 4비트, 또는 3차원 케이스에 6비트가 포함될 것이다.점이 뷰포트 위에 있으면 첫 번째 비트가 1로 설정된다.2D 아웃코드의 비트는 위, 아래, 오른쪽, 왼쪽을 나타낸다.예를 들어, 아웃코드 1010은 뷰포트의 오른쪽 상단에 있는 점을 나타낸다.
남겨진 중심부의 맞다 맨 위의 1001 1000 1010 중심부의 0001 0000 0010 밑바닥의 0101 0100 0110
자르기 발생 후 각 반복에서 엔드포인트의 아웃코드를 다시 계산해야 한다는 점에 유의하십시오.
Cohen-Sutherland 알고리즘은 직사각형 클립 창에서만 사용할 수 있다.
C/C++ 구현 예
타이피프 인트로 아웃코드; 경시하다 인트로 인사이드 = 0; // 0000 경시하다 인트로 왼쪽 = 1; // 0001 경시하다 인트로 맞다 = 2; // 0010 경시하다 인트로 맨 아래 = 4; // 0100 경시하다 인트로 톱 = 8; // 1000 // 클립을 사용하여 점(x, y)에 대한 비트 코드 계산 // 대각선으로 경계(xmin, ymin) 및 (xmax, ymax) // xmax, xmin, ymax 및 ymin이 글로벌 상수라고 가정한다. 아웃코드 ComputeOutCode(곱절로 하다 x, 곱절로 하다 y) { 아웃코드 부호를 붙이다; 부호를 붙이다 = 인사이드; // [[클립 윈도우] 내부로 초기화됨 만일 (x < xmin) // 클립 창 왼쪽 부호를 붙이다 = 왼쪽; 다른 만일 (x > xmax) // 클립 창 오른쪽 부호를 붙이다 = 맞다; 만일 (y < ymin) // 클립 창 아래 부호를 붙이다 = 맨 아래; 다른 만일 (y > 이맥스) // 클립 창 위 부호를 붙이다 = 톱; 돌아오다 부호를 붙이다; } // Cohen-Sutherland 클리핑 알고리즘에서 줄 클리핑 // P0 = (x0, y0) ~ P1 = (x1, y1)가 있는 직사각형에 대해 // (xmin, ymin)에서 (xmax, ymax)까지 대각선. 공허하게 하다 CohenSutherlandLineClipAndDraw(곱절로 하다 x0, 곱절로 하다 y0, 곱절로 하다 x1, 곱절로 하다 y1) { // P0, P1 및 클립 사각형 외부에 있는 모든 점에 대한 아웃코드를 계산하십시오. 아웃코드 아웃코드0 = ComputeOutCode(x0, y0); 아웃코드 outcode1 = ComputeOutCode(x1, y1); 바가지 긁다 받아들이다 = 거짓의; 하는 동안에 (진실의) { 만일 (!(아웃코드0 outcode1)) { // 비트 OR이 0임: 두 지점 모두 창 안쪽에 있음, 사소한 방식으로 루프 허용 및 종료 받아들이다 = 진실의; 부숴뜨리다; } 다른 만일 (아웃코드0 & outcode1) { // 비트 AND가 0이 아님: 두 점 모두 외부 영역(왼쪽, 오른쪽, 위쪽, 위쪽)을 공유함 // 또는 BO텀)이므로 둘 다 창 밖에 있어야 하며, 루프 종료(수락은 거짓) 부숴뜨리다; } 다른 { // 두 테스트 모두 실패했으므로 클리핑할 라인 세그먼트를 계산하십시오. // 외부 지점에서 클립 모서리가 있는 교차점까지 곱절로 하다 x, y; // 클립 사각형 밖에 적어도 하나의 끝점이 있으므로 선택하십시오. 아웃코드 아웃코드아웃 = outcode1 > 아웃코드0 ? outcode1 : 아웃코드0; // 이제 교차점을 찾으십시오. // 공식 사용: // 경사 = (y1 - y0) / (x1 - x0) // x = x0 + (1 / 기울기) * (ym - y0), 여기서 ym은 ymin 또는 ymax이다. // y = y0 + 기울기 *(xm - x0), 여기서 xm은 xmin 또는 xmax // 0으로 나누기를 걱정할 필요는 없다. 각각의 경우, // 테스트 중인 아웃코드 비트는 분모가 0이 아니라는 것을 보장한다. 만일 (아웃코드아웃 & 톱) { // 지점이 클립 창 위에 있음 x = x0 + (x1 - x0) * (이맥스 - y0) / (y1 - y0); y = 이맥스; } 다른 만일 (아웃코드아웃 & 맨 아래) { // 지점이 클립 창 아래에 있음 x = x0 + (x1 - x0) * (ymin - y0) / (y1 - y0); y = ymin; } 다른 만일 (아웃코드아웃 & 맞다) { // 지점이 클립 창의 오른쪽에 있음 y = y0 + (y1 - y0) * (xmax - x0) / (x1 - x0); x = xmax; } 다른 만일 (아웃코드아웃 & 왼쪽) { // 지점이 클립 창의 왼쪽에 있음 y = y0 + (y1 - y0) * (xmin - x0) / (x1 - x0); x = xmin; } // 이제 외부 점을 교차로 점으로 이동하여 클립으로 이동 // 그리고 다음 패스를 준비하십시오. 만일 (아웃코드아웃 == 아웃코드0) { x0 = x; y0 = y; 아웃코드0 = ComputeOutCode(x0, y0); } 다른 { x1 = x; y1 = y; outcode1 = ComputeOutCode(x1, y1); } } } }
메모들
- ^ Bob Sproull과 William M에 의한 대화형 컴퓨터 그래픽의 원리 124, 252 페이지.뉴먼, 1973년 맥그로-힐 교육 국제판 ISBN0-07-085535-8.
참고 항목
동일한 목적으로 사용되는 알고리즘:
참조
- 제임스 D.폴리. 컴퓨터 그래픽: 원칙과 실천.애디슨 웨슬리 프로페셔널, 1996. 페이지 113.