량-바르스키 알고리즘

Liang–Barsky algorithm

컴퓨터 그래픽스에서 Liang-Barsky 알고리즘(양유동량과 Brian A의 이름을 딴 것). Barsky)는 회선 클리핑 알고리즘입니다.Liang-Barsky 알고리즘은 선의 파라메트릭 방정식과 클리핑 창의 범위를 설명하는 부등식을 사용하여 라인과 클립 창의 교차점을 결정합니다.이러한 교차로에서는 선의 어느 부분을 그려야 하는지 알고 있습니다.이 알고리즘은 Cohen-Sutherland보다 훨씬 효율적입니다.Liang-Barsky 클리핑알고리즘의 개념은 회선교차를 계산하기 전에 가능한 한 많은 테스트를 수행하는 것입니다.

우선 직선의 일반적인 파라메트릭 형식을 고려합니다.

클립 창에 포인트가 있습니다.

그리고.

이것은 4개의 부등식으로 표현될 수 있다.

어디에

최종 선분을 계산하려면:

  1. 클리핑 창 가장자리에 평행한 선은 해당 경계에 p i { }=(를) .
  2. i < 의 경우, 회선은 완전히 외부에 있어 삭제할 수 있습니다.
  3. i < \ } <0 、 p > 、회선은 안쪽에서 바깥쪽으로 진행됩니다.
  4. 이 아닌 의 경우 i / i {\ u})는 선과 창 가장자리의 교차점에 대해 t{\ t 합니다(투영).
  5. 창 가장자리를 가진 선의 실제 교차점 2개는 다음과 같이 계산되는 설명됩니다.의 경우 p <({외부에서 내부로)의 경계를 확인합니다. 1 {i style u_중 가장 큰 값으로 합니다. 2 i> 0로부터 외부로)의 경계를 확인합니다.}})를 { i / }({ style 최소값으로 합니다.
  6. 1> 2 \ > , 회선은 클립창 밖에 있습니다. 1< < < 2\ < < < } 의 , 그 내부에는 모두 포함되어 있습니다.
// Liang: 바스키한 라인 클리핑알고리즘 #실패하다<iostream> #실패하다<고객명>님.h> #실패하다<math.h>  사용. 네임스페이스 표준;  // 이 함수는 최대값을 제공합니다. 흘러가다 맥시(흘러가다 arr[],인트 n) {   흘러가다 m = 0;   위해서 (인트 i = 0; i < > n; ++i)     한다면 (m < > arr[i])       m = arr[i];   돌아가다 m; }  // 이 함수는 최소값을 제공합니다. 흘러가다 미니(흘러가다 arr[], 인트 n) {   흘러가다 m = 1;   위해서 (인트 i = 0; i < > n; ++i)     한다면 (m > arr[i])       m = arr[i];   돌아가다 m; }  무효 양_바스키_클리퍼(흘러가다 xmin, 흘러가다 ymin, 흘러가다 xmax, 흘러가다 최대,                           흘러가다 x1, 흘러가다 y1, 흘러가다 x2, 흘러가다 y2) {   // 변수 정의   흘러가다 p1 = -(x2 - x1);   흘러가다 p2 = -p1;   흘러가다 p3 = -(y2 - y1);   흘러가다 p4 = -p3;    흘러가다 문제 1 = x1 - xmin;   흘러가다 문제 2 = xmax - x1;   흘러가다 문제 3 = y1 - ymin;   흘러가다 문제 4 = 최대 - y1;    흘러가다 포사르[5], 부정[5];   인트 포즈인드 = 1, 부정하다 = 1;   포사르[0] = 1;   부정[0] = 0;    직사각형(xmin, ymin, xmax, 최대); // 클리핑 창 그리기    한다면 ((p1 == 0 & & 문제 1 < > 0)    (p2 == 0 & & 문제 2 < > 0)    (p3 == 0 & & 문제 3 < > 0)    (p4 == 0 & & 문제 4 < > 0)) {       텍스트 이외의(80, 80, "라인은 클리핑 창과 평행합니다!");       돌아가다;   }   한다면 (p1 != 0) {     흘러가다 r1 = 문제 1 / p1;     흘러가다 r2 = 문제 2 / p2;     한다면 (p1 < > 0) {       부정[부정하다++] = r1; // 음의 p1의 경우 음의 배열에 추가합니다.       포사르[포즈인드++] = r2; // 및 p2를 양의 어레이에 추가합니다.     } 또 다른 {       부정[부정하다++] = r2;       포사르[포즈인드++] = r1;     }   }   한다면 (p3 != 0) {     흘러가다 r3 = 문제 3 / p3;     흘러가다 r4 = 문제 4 / p4;     한다면 (p3 < > 0) {       부정[부정하다++] = r3;       포사르[포즈인드++] = r4;     } 또 다른 {       부정[부정하다++] = r4;       포사르[포즈인드++] = r3;     }   }    흘러가다 xn1, yn1, xn2, yn2;   흘러가다 rn1, rn2;   rn1 = 맥시(부정, 부정하다); // 최대 음수 배열   rn2 = 미니(포사르, 포즈인드); // 최소 양의 배열    한다면 (rn1 > rn2)  { // 거부     텍스트 이외의(80, 80, "라인이 클리핑 창 밖에 있습니다!");     돌아가다;   }    xn1 = x1 + p2 * rn1;   yn1 = y1 + p4 * rn1; // 새로운 포인트 계산    xn2 = x1 + p2 * rn2;   yn2 = y1 + p4 * rn2;    세트 컬러(시안);    (xn1, yn1, xn2, yn2); // 새 선 그리기    세트라인 스타일(1, 1, 0);    (x1, y1, xn1, yn1);   (x2, y2, xn2, yn2); }  인트 주된() {   외치다 << > "\nLiang-barsky 라인 클리핑";   외치다 << > "\n시스템 윈도우의 지출은 (0,0)이 왼쪽 하단에 있고 (631,467)이 오른쪽 상단에 있습니다.;   외치다 << > "\n창의 좌표(wxmin, wxmax, wymin, wymax):;   흘러가다 xmin, xmax, ymin, 최대;    >> xmin >> ymin >> xmax >> 최대;   외치다 << > "\n선의 끝점(x1, y1) 및 (x2, y2)을 입력합니다.;   흘러가다 x1, y1, x2, y2;    >> x1 >> y1 >> x2 >> y2;    인트 gd = 검출하다, gm;    // C++용 winbgim 라이브러리 사용, 그래픽 모드 초기화   초기화(&gd, &gm, "");   양_바스키_클리퍼(xmin, ymin, xmax, 최대, x1, y1, x2, y2);   취득하다();   클로즈그래프(); } 

「 」를 참조해 주세요.

같은 목적으로 사용되는 알고리즘:

레퍼런스

외부 링크