코언-서덜랜드 알고리즘

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);    }   }  } } 

메모들

  1. ^ Bob Sproull과 William M에 의한 대화형 컴퓨터 그래픽의 원리 124, 252 페이지.뉴먼, 1973년 맥그로-힐 교육 국제판 ISBN0-07-085535-8.

참고 항목

동일한 목적으로 사용되는 알고리즘:

참조

외부 링크